I'm facing an issue in javascript while submitting date. If I submit a date with year as 0001 or 0798 js is converting it into 1, 789.how can i submit date with year as 0001 or 0789 or whatever year I give?.
In firebug console you can try this to see.
Ex: d = new Date
Sun Jan 26 2014 18:35:49 GMT+0530 (IST)
d.setFullYear(0001)
-62133389650691
d
Fri Jan 26 1 18:35:49 GMT+0530 (IST)
Please help me.
The year of a date is not a string, it's a number.
The string returned by Date#toString is not (curiously) specified by the specification. It can be whatever the engine wants it to be. Some engines (such as V8 in Chrome) output just as much of the year as is required, so 1 or 789 or 2014 or 12487. There's nothing special about years that makes them four digits long, after all; it just happens that we live during the 9,000-year period (1000 -> 9999) during which years in our Western calendar (Gregorian calendar, specifically) have four digits.
If you want a string in a particular format (other than the near-ISO format the ES5 spec added via toISOString, on engines that support it), you have to format it yourself (or use an add-on library like MomentJS or similar to do so).
Related
Output from Chrome 66 debug console with Hongkong timezone:
Valid date:
new Date('2018-06-30')
Sat Jun 30 2018 08:00:00 GMT+0800 (China Standard Time)
Invalid date gives T+1 value!
new Date('2018-06-31')
Sun Jul 01 2018 08:00:00 GMT+0800 (China Standard Time)
Finally... and invalid date error.
new Date('2018-06-32')
Invalid Date
Why does June 31 give T+1?
The JavaScript Date object is happy to handle unit rollover for you, that's all that's going on with the 2018-06-31 example — it's handling the rollover from June 30th to July 1st.
It doesn't do that for the 2018-06-32 example because 32 is an invalid value for the days field (whereas 31 isn't, it's just that June only has 30 days). The spec defines the valid ranges for the parts of the date/time string here, where we can see it says the valid values for the day of the month are 01 to 31 inclusive.
It's probably worth noting that the parsing of that ISO-8601-derived format (it isn't ISO-8601, quite) if you don't include a timezone indicator has a checkered history, sadly. ES5 specified ISO-8601 but got the meaning of the absense of a timezone indicator wrong (it said it should mean UTC, but ISO-8601 says it means local time); then ES2015 tried to fix that, but conforming to ES2016's rules would have broken a substantial amount of real-world code; and so it wasn't stabilized until ES2016, which says: Date-only forms (like yours) without a timezone indicator are UTC, date/time forms without one are local time. (It's been fine for years if you do include a timezone indicator.)
Trying to support Javascript's new Date().toString() output format with Java's DateTimeFormatter but can't seem to make it work.
Js output is of the following nature:
Wed Apr 04 2018 09:56:16 GMT-0500 (SA Pacific Standard Time)
Wed Apr 04 2018 16:12:41 GMT+0200 (CEST)
My current formatter:
int defaultOffset = ZonedDateTime.now().getOffset().getTotalSeconds();
DateTimeFormatter dtfJs = new DateTimeFormatterBuilder()
.appendPattern("EE MMM dd yyyy HH:mm:ss [OOOO (zzzz)]")
.parseDefaulting(ChronoField.OFFSET_SECONDS,defaultOffset
.toFormatter();
If i .parse() those date strings from js, I get the following error:
[date] could not be parse at index 25
Index 25 for both the dates mentioned is:
GMT-0500 (SA Pacific Standard Time)
GMT+0200 (CEST)
I know the problem is with the : (colon) because if I print the current date with dtfJs, I get:
Wed Apr 04 2018 10:25:10 GMT-05:00 (Colombia Time)
So the part of the GMT-05:00 is exected as GMT-0500 in the string recieved but I can't find a reserved pattern letter which matches this.
The docs say:
Offset O: This formats the localized offset based on the number of
pattern letters. One letter outputs the short form of the localized
offset, which is localized offset text, such as 'GMT', with hour
without leading zero, optional 2-digit minute and second if non-zero,
and colon, for example 'GMT+8'. Four letters outputs the full form,
which is localized offset text, such as 'GMT, with 2-digit hour and
minute field, optional second field if non-zero, and colon, for
example 'GMT+08:00'. Any other count of letters throws
IllegalArgumentException.
Offset Z: This formats the offset based on the number of pattern
letters. One, two or three letters outputs
the hour and minute, without a colon, such as '+0130'. The output will
be '+0000' when the offset is zero. Four letters outputs the full form
of localized offset, equivalent to four letters of Offset-O. The
output will be the corresponding localized offset text if the offset
is zero. Five letters outputs the hour, minute, with optional second
if non-zero, with colon. It outputs 'Z' if the offset is zero. Six or
more letters throws IllegalArgumentException.
Which means that the four letter will output always with colon ":", thus throwing DateTimeParseException
Help greatly appreciated, thanks
Edit
Thanks to #mszymborski I managed to pass on to validate the parenthesis part "(CEST)", what would be useful here ?
I tried with EE MMM dd yyyy HH:mm:ss 'GMT'Z (zz) but this only works with the second date in the list, not the first
GMT-0500 (SA Pacific Standard Time) ERROR
GMT+0200 (CEST) PASS
Dates in JavaScript is a big mess. toString() is not only browser/implementation dependent, but also locale sensitive. I'm in Brazil, so my browser is set to Portuguese, and new Date().toString() gives this result:
Wed Apr 04 2018 14:14:04 GMT-0300 (Hora oficial do Brasil)
Month and day-of-week names are in English, but the timezone name is in Portuguese. What a mess!
Anyway, to parse those strings, you have to make some decisions.
Do you need to get the timezone or just the offset?
The offset GMT+0200 is used by more than one country (hence, more than one timezone uses it). Although the offset is enough to have a non-ambiguous point in time, it's not enough to know the timezone.
Even short names such as CEST are not enough, because this is also used by more than 1 country.
If you want to parse just the offset, the best way is to simply remove everything after the ( and parse it to an OffsetDateTime:
DateTimeFormatter parser = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z", Locale.US);
// 2018-04-04T16:12:41+02:00
OffsetDateTime.parse("Wed Apr 04 2018 16:12:41 GMT+0200", parser);
Also note that I used a java.util.Locale. That's because the month and day of week are in English, and if you don't set a locale, it'll use the JVM default - and you can't guarantee that it'll always be English. It's better to set a locale if you know in what language the inputs are.
If you need to get the timezones, though, it's more complicated.
Names like "CEST" are ambiguous, and you need to make arbitrary choices for them. With java.time is possible to build a set of preferred timezones to be used in case of ambiguities:
Set<ZoneId> zones = new HashSet<>();
zones.add(ZoneId.of("Europe/Berlin"));
zones.add(ZoneId.of("America/Bogota"));
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z (")
// optional long timezone name (such as "Colombia Time" or "Pacific Standard Time")
.optionalStart().appendZoneText(TextStyle.FULL, zones).optionalEnd()
// optional short timezone name (such as CET or CEST)
.optionalStart().appendZoneText(TextStyle.SHORT, zones).optionalEnd()
// close parenthesis
.appendLiteral(')')
// use English locale, for month, timezones and day-of-week names
.toFormatter(Locale.US);
With this, you can parse your inputs to a ZonedDateTime:
// 2018-04-04T16:12:41+02:00[Europe/Berlin]
ZonedDateTime.parse("Wed Apr 04 2018 16:12:41 GMT+0200 (CEST)", fmt);
// 2018-04-04T10:25:10-05:00[America/Bogota]
ZonedDateTime.parse("Wed Apr 04 2018 10:25:10 GMT-0500 (Colombia Time)", fmt);
But unfortunately, this doesn't parse the "SA Pacific Standard Time" case. That's because the timezones names are built-in in the JVM and "SA Pacific Standard Time" is not one of the predefined strings.
A good alternative is to use the mapping suggested by M.Prokhorov in the comments: https://github.com/nfergu/Java-Time-Zone-List/blob/master/TimeZones/src/TimeZoneList.java
Then you manually replace the name in the string and parse it with VV pattern (instead of z), because the mapping uses IANA's names (such as Europe/Berlin, which are parsed by VV).
But the best alternative is to use toISOString(), which produces strings in ISO8601 format, such as 2018-04-04T17:39:17.623Z. The big advantage is that java.time classes can parse it directly (you don't need to create a custom formatter):
OffsetDateTime.parse("2018-04-04T17:39:17.623Z");
This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 6 years ago.
I feel like I am missing something here.
The Date.getDay() method is supposed to return a value from 0-6. 0 for Sunday and 6 for Saturday.
Now I have two dates, both are 'Sunday' which should return 0.
new Date('1990-11-11').getDay() // returns 6
new Date('2016-1-3').getDay() // returns 0
What is causing the discrepancy? I dare to question the validity of the .getDay() method, but I can't figure out what is going on.
EDIT
> new Date('1990-11-11')
Sat Nov 10 1990 17:00:00 GMT-0700 (MST)
> new Date('2016-01-03')
Sat Jan 02 2016 17:00:00 GMT-0700 (MST)
> new Date('2016-1-3') // they say this format is wrong, but it returns the right date
Sun Jan 03 2016 00:00:00 GMT-0700 (MST)
I don't understand what is going on. January 3rd is Sunday and November 11th 1990 is Sunday. Why is it saying Saturday?
The one that is wrong is the one that returns Sunday, and that must be because the format is incorrect. 1990-11-11 is interpreted as 00:00:00 on midnight of the 11th, UTC, which is 5pm on Saturday the 10th in your time zone.
If you use getUTCDay(), you should get 0 for both dates.
new Date('1990-11-11').getUTCDay() // returns 0
new Date('2016-01-03').getUTCDay() // returns 0
Certainly, your claim that 1990-11-11 is Sunday is true but you have to understand that JavaScript Date object:
Handles time as well as date
Is time zone aware
Is poorly designed and rather counter-intuitive
Your own tests illustrate this:
new Date('1990-11-11').getDay() // returns 6
> new Date('1990-11-11')
Sat Nov 10 1990 17:00:00 GMT-0700 (MST)
What happens is that constructor assumes local time or UTC depending on the syntax used:
Note: Where Date is called as a constructor with more than one
argument, the specifed arguments represent local time. If UTC is
desired, use new Date(Date.UTC(...)) with the same arguments.
Note: parsing of date strings with the Date constructor (and
Date.parse, they are equivalent) is strongly discouraged due to
browser differences and inconsistencies. Support for RFC 2822 format
strings is by convention only. Support for ISO 8601 formats differs in
that date-only strings (e.g. "1970-01-01") are treated as UTC, not
local.
... and your syntax makes it as UTC. But many others methods assume local time:
The getDay() method returns the day of the week for the specified date
according to local time, where 0 represents Sunday.
getDay returns day index (from 0 to 6), where 0 is Sunday.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay
Return value:
An integer number corresponding to the day of the week for the given date, according to local time: 0 for Sunday, 1 for Monday, 2 for Tuesday, and so on.
Update:
new Date constructor returns different time values for those dates.
new Date('2016-1-3')
==> Sun Jan 03 2016 00:00:00 GMT+0100 (CET)
new Date('1990-11-11')
==> Sun Nov 11 1990 01:00:00 GMT+0100 (CET)
And for some reason, the first one gets interpreted as Saturday on your machine.
Sorry for not being able to help out more
Update2:
Using two digits for month/day should standardize the results.
Example:
(new Date('2016-01-03')).getDay() ==> 0
This question already has an answer here:
HTML Input type datetime-local setting the wrong time-zone
(1 answer)
Closed 7 years ago.
I'm writing a MVC 5 web application. Into this, I have multiple lists that I propagate and manage through javascript and jquery (one dataset, dependent select controls, and adding ajax callbacks would complicate it unnecessarily.)
The issue I have is: I have a hidden for field formatted to ISO 8601. I run into issues when I display the date in the user's local time, I get a shifted date.
So if the date were stated as: 01-01-2009 (in iso 8601 format: 2009-01-01), the user sees: 12-31-2008.
When I parse the date I'm using:
this.date = new Date(Date.parse(originalString));
/* ^- Date.parse is giving me a number. */
To display the text of the date I am using:
admin.date.toLocaleDateString().Concat(...
Do I need to do any sort of patch-up to adjust things to the proper time-zone? The date, when using console.log(admin.date); shows the original 2009-01-01
I'm thinking there's some parameter I'm not specifying correctly in the toLocaleDateString, but my familiarity level with it is low.
Edit: The goal is to prevent the date shift. All we store is the date, the time aspect is dropped. We have multiple time-zones posting to this database, and the goal is: We use the date of the person who posted it, time dropped. Were the date May 01, 2015, I want anyone who sees that date to see May 01, 2015, the 'toLocaleDateString' is merely a means to get it to appear format correct for their region. So someone who views dates as yyyy-mm-dd will see it properly.
Based on the documentation for Date.parse:
The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC.
You are getting back the epoch time in UTC for your parsed date string hence why the date is off for local times. So, you would need to know the time difference between the local time and UTC which Date.getTimezoneOffset provides (in minutes) in order to set the correct date for the local time:
> var date = new Date(Date.parse('2009-01-01'));
undefined
> date;
Wed Dec 31 2008 19:00:00 GMT-0500 (EST)
> date.getTimezoneOffset();
300
> date.setMinutes(date.getTimezoneOffset());
1230786000000
> date;
Thu Jan 01 2009 00:00:00 GMT-0500 (EST)
One thing to note though is:
...the offset is positive if the local timezone is behind UTC and negative if it is ahead.
So you might need to take care for locales where the value is negative if this applies to your application. If so maybe just omitting negative values would be enough since the date should be the same if a locale's timezone is ahead of midnight UTC.
EDIT: To compensate for possible issues with daylight savings time:
> var dateVals = String.prototype.split.call('2009-01-01', '-');
undefined
> var date = new Date(dateVals[0], dateVals[1] - 1, dateVals[2]);
undefined
> date
Thu Jan 01 2009 00:00:00 GMT-0500 (EST)
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