moment.js - format string with century - javascript

I'm trying to get a moment object which matches July 8th 2021 from this code:
moment('121 07 08', 'CYY MM DD')
I'm trying to use century since the value is coming from a legacy database and it seems like moment.js doesn't support it. This is not the only instance of it, so I'm trying to figure out the best way to handle it.
Any ideas?

There isn't a century modifier in moment, but 2 digit years where the values are less than 68 are assumed to be in the year 2000, per the docs:
Parsing two digit years
By default, two digit years above 68 are assumed to be in the 1900's
and years 68 or below are assumed to be in the 2000's. This can be
changed by replacing the moment.parseTwoDigitYear method.
C is ignored so it will see the 12 as the 2-digit year. Remove the C and the 1 and you're set.
console.log(moment('21 07 08', 'YY MM DD').format('MMMM Do YYYY'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment-with-locales.min.js"></script>

Related

Moment.js incorrect date for week number

This should return the last week of the year:
moment().year('2021').week(51).day('monday').format('YYYY-MM-DD');
But instead it is returning 2022-12-12. I think there is a bug in moment.js.
Here is codepen: https://jsfiddle.net/5402bkmp/
You should post your code here, not elsewhere.
var now = moment().year('2021').week(51).day('monday').format('YYYY-MM-DD');
console.log(now.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
Breaking down the code, if run on Monday 27 December:
moment()
Creates a moment object for 27 Dec 2021
.year('2021')
Sets the year to 2021, which changes nothing because it's already set to 2021. It also handles cases like 2020-02-29 + 1 year, which becomes 2021-02-28.
.week(51)
Sets to "localised" start of week 51. The problem is, how does the user know how moment.js localises things? For me it seems to be Sun 12 Dec 2021. That numbering seems to be based on the first week starting on the first Sunday on or before 1 Jan 2021 (i.e. Sun 27 Dec 2020), e.g. new Date(2020, 11, 27 + 50*7) gives 12 Dec 2021.
.day('monday')
Sets the date to Monday of the same localised week, again it's hard for users to know what their "localised" week is. For me, it just keeps it as Monday because it seems the localised week starts on Sunday (my PC is set to start weeks on Monday).
.format('YYYY-MM-DD')
So I think it's clear that a problem with using the week method is that neither the programmer nor user know what the result will be because they don't know what moment.js is using to localise things (possibly navigator.language). And results can be very different to what is expected.
One fix, as Sergiu suggested, is to use isoWeek so at least the result is consistent and predictable. ISO weeks start on Monday, with the first week being the one with the most days in the subject year. It's also expressed as the week of the first Thursday, or the week of 4 January, they all work to give the same Monday as the start of week 1 of any particular year. Some years have 52 weeks, some 53, and usually a couple of days near the end of the year are part the first week of the following year or last week of the previous year.
You might also like to see Get week of year in JavaScript like in PHP.
You need to use .isoWeek instead of .week (documented here, though it's unclear to me why).
That's works really good to me!
moment.locale("myLanguage", { week: { dow: 0 }});
momentExt.updateLocale("myLanguage", { week: { dow: 0 }});
Example here: https://jsfiddle.net/naqr7upL/

Bug in JavaScript date 1 Jan 0099

On 1 jan 0099 there was Thrusday but it return. Friday
days = new Date(" January 1 ,0099")
day = days.getDay()
alert(day);
RESULT
5
But it should return 4
Basically, it appears Javascript won't construct a Date in the year 99:
year
Integer value representing the year.
Values from 0 to 99 map to the years 1900 to 1999. All other values are the actual year.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#Syntax
You can try with different formats, 99 always appears to map to 1999. Likely this was implemented as a workaround and/or “convenience” for Y2K dates, perhaps even inherited from Java.
I'm not sure if there's a better workaround, but this works:
let d = new Date(100, 0, 1);
d.setFullYear(99);

Date difference when year is smaller than zero

If I'm executing this:
var date = new Date("10.31");
date.setFullYear(-125);
the output of date is Sun Oct 31 -125 00:00:00 GMT+0200 (W. Europe Summer Time)
If I check this on wolframalpha the day seems to be tuesday.
Can someone explain why not the same day is displayed by both source?
The reason for the difference between JavaScript and wolframalpha website is that JavaScript is calculating the years mathematically, so it includes the year zero. Try to set the year to zero in JavaScript and you will see that it works. However, there is no such a thing as year zero, and the year before year 1 is year 1 BC. Try to set the year to zero on wolframalpha website and you get an error, while it automatically converts all negative years to years BC. This is the correct behavior.
To get the BC years in JavaScript, add 1 to every year below 1. So year 0 becomes 1BC, and year -125 becomes 126BC. In JavaScript this gives you Sunday, and 126BC on wolframalpha website gives you Sunday too. 125BC gives you Tuesday on wolframalpha website, and -124 gives you the same in JavaScript.
var date = new Date();
date.setFullYear(-124);
date.setMonth(9);
date.setDate(31);
console.log(date.toString());
date.setFullYear(-125);
console.log(date.toString());
negative years in javascript do produce a BC date but it's kind of a poor design. Wolfram Alpha is probably correct. See this answer for more: Why does Date accept negative values?
Javascript dates start in 1970.
Let's do a quick count.
(new Date()).setYear(-125); //returns -66085584766591 (milliseconds from time 0)
//Let's convert those milliseconds in years...
//-66085584766591 = -2095,56 (years???)
As you can see, you can't rely on negative dates in Javascript.

Verify date with regular expressions [duplicate]

This question already has answers here:
How to write regex to validate dates?
(7 answers)
Closed 7 years ago.
date format is 2015/04/25
I am trying
^\d{4}\/\d{2}\/\d{2}$
And its working fine, But i want to validate that the month should b less then 12 and date less then 31
I had tried this
^\d{4}\/(\d{2}\<[12])\/\d{2}$
But it is not working.
PS: I am very noob in regular expressions.
You can use
^\d{4}\/(0\d|1[0-2])\/([0-2]\d|3[01])$
Explanation:
\d{4} any four digits
(0\d|1[0-2]) 0(any digit) or 1(0 to 2) i.e 00 to 09 or 10-12
([0-2]\d|3[01]) (0 to 2)(any digit) or 3(0 or 1) i.e 00 to 29 or 30 or 31
Edit1: If you want to match from 01-12 only for months and 01-31 only for day (without 00) you can use :
^\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])$
Edit2: If you want strict validation of dates use explode and checkdate.. as suggested by #Wayne.. since it also includes validation of leap years.
See Demo
As jeroen pointed out above, the best solution would be to use a combination of the functions explode and checkdate. A regex isn't going to catch dates that never occurred.
$exploded = explode("/", $date);
if(checkdate($exploded[1], $exploded[2], $exploded[0])){
//Valid date.
}
PS, you might also want to check the number of elements in the $exploded array, seeing as you're expecting three strings.
here is extended version of the same principle shown by used #karthik manchala
^((\d{4}\/(0[469]|11)\/(0[1-9]|1\d|30))|(\d{4}\/(0[13578]|1[02])\/([0-2]\d|3[01]))|(\d{4}\/(02)\/(0[1-9]|[12]\d)))$
it will filter as well 30 vs 31 and everything above 29 for february. It will not recognise when to use 28 and 29 in february though.
If you want to capture leap year you can do it easily if it is recent date or date in near future as it is divisible by 4, you can capture 2000, 2004, 2008, 2012 etc. but the rule is not consistent.

date validation in classic asp

date validation in classic asp
i am new in classic asp and having problem in validating the date
dim Day,Month,Year,FullDate
Day = "01"
Month = "20"
Year = "2012"
FullDate = Month + "/" + Day + "/" + Year
document.write FullDate
document.write IsDate(FullDate)
document.write IsDate(CDate(FullDate))
document.write IsDate(20/01/2012)
output :
20/01/2012
true true false
If you're asking why document.write IsDate(20/01/2012) doesn't write true the reason is because you've asked the computer to do division, then evaluate that as a date.
20/01 = 20 => 20/2012 ~= 0.01
IsDate(0.01) => false
If you really want to test what you've got try this instead (small tweak)
Your: document.write IsDate(20/01/2012)
Mine: document.write IsDate("20/01/2012")
Also, just for clarification http://en.wikipedia.org/wiki/Date_format_by_country
Some countries use
dd/mm/yyyy
and some places use
mm/dd/yyyy
and that's why the International Standards Organization suggests you do things with least specificity to most specificity:
yyyy-mm-dd hh:mm:ss.ffffffffffff
Notice that's Years -> Months (which month is more specific than which year) -> Days (which day an event occurs on is helpful) -> Hours (don't be late!) -> Minutes (saved by the bell?) -> Seconds (Now you have some idea when it happened) -> fractions of a second (Olympic Swimming!!)
Years are rather non-specific. Lots of things happen in one year. So those should always parse first. The ISO way is the preferred way to pass Date information, and when the year does not come first, the system tries to guess intelligently. Since some parts of the world do dmy and some do mdy and since only one of your starting two numbers is over 12, it assumes you mean dmy instead of mdy. No WTF here.
For the record, here are a list of countries which predominantly put the month first as a matter of tradition in mdy format (excluding ISO formatting which is not tradition, but science)
Belize
Federated States of Micronesia
Palau
United States of America
And finally if you want to write a function that will try and reparse the date for you:
Consider that people tend to break the date with either spaces, periods, hyphens or slashes, they may write it as "20120817" or they may include the time as well. There may be a T in the middle, and it may have a Z at the end.
Sample inputs: (and the date they represent)
2011-08-17 (august 17th)
2011-08-01 (august 1st or jan 8th?)
08-01-2011 (august 1st or jan 8th?)
08-17-2011 (august 17th)
17-08-2011 (august 17th)
2011-17-08 (I've never seen this ever)
2011/08/17 (august 17th)
2011.08.01 (august 1st or jan 8th?)
08\01\2011 (august 1st or jan 8th?)
08-17-2011 (august 17th)
17 08 2011 (august 17th)
As you can see, there's a fair bit of parsing that has to happen here, and that's to assume that they have a 10 digit string and that that 10 digits is a date. Here are some other date formats:
08-01-12 (was that January 8th, 2012 or January 12th, 2008 or August 1st, 2012 ...)
15-03-13 (ok, so we have found the month is March, but the other two?)
1-1-1
8-8-8 (these two are easy, but which rule do they match?)
And then you have to parse
20120817
20121708
20120801
01082012
08172012
So as you can see, parsing the function seems easy but there's a lot to consider, and this is JUST dates. Want to let's talk about times next?
201208171311 -> 2012-08-17 13:11 (1:11 PM)
20120817T1311 -> 2012-08-17 13:11 (1:11 PM)
20120817T0111P -> 2012-08-17 01:11 PM

Categories

Resources