Inconsistent behavior of toLocaleString() in different browser - javascript

I am working on a project where I have to deal a lot with Date and Time. Server side technology is ASP.Net and at client side I am using jQuery and jQuery Week Calendar(a jQuery plugin).
So here is the problem described, I am receiving Data Time from server something like this 2012-11-13T04:45:00.00 in GMT format.
Now at client side, I want this Date Time to be converted to Locale Date Time Format, like whatever is could be IST, EST, PKT, etc.
To achieve this, I am using JavaScript method toLocaleString(). This only works fine in Chrome, in other browser it works inconsistently.
Here are its outputs in different browsers:
Google Chrome(Works fine):
Call:
new Date ("2012-11-13T04:45:00.00").toLocaleString();
Output:
Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
Mozilla Firefox:
Call:
new Date ("2012-11-13T04:45:00.00").toLocaleString();
Output:
Tuesday, November 13, 2012 4:45:00 AM
Safari:
Call:
new Date ("2012-11-13T04:45:00.00").toLocaleString();
Output:
Invalid Date
Internet Explorer:
Call:
new Date ("2012-11-13T04:45:00.00").toLocaleString();
Output:
Tuesday, November 13, 2012 4:45:00 AM
For now these are the browsers where I tested.
Here is the Question:
I need a way to convert Data Time(having format like this 2012-11-13T04:45:00.00) To Locale Date and Time, no matter which browser client is using.

The short answer is no. toLocaleString can be implemented however the developers wish. What your question implies is that Chrome outputs the string you want.
If you would like to output that format consistently you'll need to use a separate library - like DateJS.
To do this with DateJS will need some standard format specifiers available in core.js and some that are only available in extras.js. The documentation has a list of all the format specifiers.
The string you want is:
Tue Nov 13 2012 10:15:00 GMT+0530 (India Standard Time)
So to get this from DateJS you'll need:
"D M d Y H:i:s \G\M\TO (e)"
The syntax for DateJS is:
new Date ("2012-11-13T04:45:00.00").format("D M d Y H:i:s \G\M\TO (e)");

Instead of using toLocaleString() which is outdated and implemented incorrectly for all web browsers, I strongly suggest using Globalize for date & time formatting.
Then to format date on the client side, all you have to do is to assign valid culture and simply call the format function:
Globalize.culture(theCulture);
Globalize.format( new Date(2012, 1, 20), 'd' ); // short date format
Globalize.format( new Date(2012, 1, 20), 'D' ); // long date format
Pretty simple, isn't it? Well, you'll have to also integrate it with your ASP.Net application, which complicates things a bit. First, you will need to reference the globalize.js the regular way:
<script type="text/javascript" src="path_to/globalize.js"></script>
Then it is best to include the right culture definition, that is the one you will need to use when formatting:
<script type="text/javscript" src="path_to/cultures/globalize.culture.<% = CultureInfo.CurrentCulture.ToString() %>.js"></script>
Finally you will need to set theCulture variable before you use it:
<script type="text/javscript">
var theCulture = <% = CultureInfo.CurrentCulture.ToString() %>
</script>
Of course the more elegant way to do it, would be to create a property or the method in the code-behind that will write down the appropriate scripts for you and then reference just the method, say:
public string IntegrateGlobalize(string pathToLibrary)
{
var sb = new StringBuilder();
sb.Append("<script type=\"text/javascript\" src=\"");
sb.Append(pathToLibrary);
sb.AppendLine("/globalize.js\"></script>");
sb.Append("<script type=\"text/javascript\" src=\"");
sb.Append(pathToLibrary);
sb.AppendLine("/cultures/globalize.culture.");
sb.Append(CultureInfo.CurrentCulture);
sb.AppendLine(\"></script>");
sb.Append("<script type=\"text/javascript\">");
sb.Append("var theCulture = ");
sb.Append(CultureInfo.CurrentCulture);
sb.AppendLine(";</script>");
return sb.ToString();
}
Then all you have to do, is to reference this method in the (master?) page head:
<head>
<% = IntegrateGlobalize("path_to_globalize") %>
...
</head>
Some issues
If you want to do it 100% correctly, you will need to enhance the Globalize culture generator to include 'g' format switch and then use this exact switch on the client side to format date:
Globalize.format( new Date(2012, 1, 20), 'g' ); // default date format
Why is that? Because 'g' is a default date format. This is what you'll get when you simply call DateTime's ToString() method without parameters (which will imply CultureInfo.CurrentCulture as the only parameter...). The default format is best, it will be either short or long, or any other, but the most commonly used by people using this culture.
I said that toLocaleString() is wrong for all web browsers. Why is that? That's because it will use web browsers settings and not the server-side detected culture. That means, that you might have mixed cultures in the same web page. That may happen if some of your dates are formatted on the server side and some other on the client side. That's why we needed to pass (detected) culture from the server side.
BTW. If you decide to include the regional preferences dialog to your web application, the mismatch would be even more visible, as toLocaleString() won't follow user settings...

To convert a time to a locale-specific string on the server, you can use the method DateTime.ToLongDateString. On that page, see the note about the "current culture object" (on the server) of class DateTimeFormatInfo. Make sure that's set correctly.

The root cause of this issue was never addressed by any of the answers. The OP said:
I am receiving Data Time from server something like this 2012-11-13T04:45:00.00 in GMT format.
GMT is not a format. This string is in ISO 8601 extended format, without any time zone specified. The ISO 8601 spec says that without a qualifier, this is intended to represent local time. To specify GMT, you would append a Z to the end, or you could append an offset such as +00:00.
The problem is, ECMAScript (v1 - v5.1) did not honor this provision in the spec. It actually said that should be interpreted as UTC instead of local time. Some browsers honored the ISO spec, some honored the ECMA spec. This has been corrected for version 6, and most browsers have complied.
So - if you intend to transmit UTC/GMT based timestamps, then on the server side, you should always send a Z so there is no ambiguity.
Still, even if the value is correctly interpreted, there's no guarantee that the strings will be formatted the same across browsers. For that, you do indeed need a library. I recommend moment.js, but there are others.

Related

How to find the timeZoneOffset added in Date object [duplicate]

I have a string representing the current time: 2015-11-24T19:40:00. How do I parse this string in Javascript to get a Date represented by this string as the LOCAL TIME? Due to some restriction, I cannot use the library moment, but jquery is allowed. I know that someone has asked this question before, but the answer used moment
For example, if I run the script in California, then this string would represent 7PM pacific time, but if I run the script in NY then this string would represent Eastern Time?
I tried the following but Chrome and Firefox give me different results:
var str = "2015-11-24T19:40:00";
var date = new Date(str);
Chrome consumes it as UTC time (Tue Nov 24 2015 11:40:00 GMT-0800 (Pacific Standard Time)),
but Firefox consumes it as my local PACIFIC time (Tue Nov 24 2015 19:40:00 GMT-0800 (Pacific Standard Time))
I tried adding "Z" to str, like this var date = new Date(str+"Z");, then both browsers give me UTC time. Is there any similar letter to "Z" which tells all browsers (at least chrome, Firefox and Safari) to parse the string as local time zone?
Parsing of date strings using the Date constructor or Date.parse (which are essentially the same thing) is strongly recommended against.
If Date is called as a function and passed an ISO 8601 format date string without a timezone (such as 2015-11-24T19:40:00), you may get one of the following results:
Pre ES5 implementaitons may treat it as anything, even NaN (such as IE 8)
ES5 compliant implementations will treat it as UTC timezone
ECMAScript 2015 compliant implementations will treat it as local (which is consistent with ISO 8601)
A Date object has a time value which is UTC, and an offset based on system settings. When you send a Date to output, what you see is usually the result of Date.prototype.toString, which is an implementation dependent, human readable string representing the date and time, usually in a timezone based on system settings.
The best way to parse date strings is to do it manually. If you are assured that the format is consistent and valid, then parsing an ISO format string as a local date is as simple as:
/* #param {string} s - an ISO 8001 format date and time string
** with all components, e.g. 2015-11-24T19:40:00
** #returns {Date} - Date instance from parsing the string. May be NaN.
*/
function parseISOLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}
document.write(parseISOLocal('2015-11-24T19:40:00'));
Note that parsing of ISO strings using Date.parse only accepts UTC, it does not accept any other timezone designation (noting the above behaviour if it's missing).
A variation on RobG's terrific answer.
Note that this will require that you run bleeding edge JavaScript as
it relies on the arrow notation and spread operator.
function parseDateISOString(s) {
let ds = s.split(/\D/).map(s => parseInt(s));
ds[1] = ds[1] - 1; // adjust month
return new Date(...ds);
}
Note that this doesn't take into account if the date/time given is in any timezone. It will assume local time. You can change new Date for Date.UTC to assume UTC.
There are technical reasons for why you would write you code like this. For example, here we apply the correct number of arguments, with their corresponding expected type. It's true that the Date constructor will turn strings into numbers but what could be happening is that there's a deoptimization taking place where the optimized code is expecting a number but sees a string and takes a slower path. Not a big deal but I try to write my JavaScript to avoid such things. We also won't be indexing outside the bounds of the array if less than 6 components can be found in the string which is also one of those things you can do in JavaScript but it has subtle deoptimization caveats.
Where Date is called as a constructor with more than one argument, the specified arguments represent local time.
I also have a much faster way than using the string.split() because we already know where the numbers are:
return new Date(Number(date.substring(0, 4)), Number(date.substring(5, 7))-1,
Number(date.substring(8, 10)), Number(date.substring(11, 13)),
Number(date.substring(14, 16)), Number(date.substring(17, 19)));
This will work with and/or without the 'T' and 'Z' strings and still has decent performance. I added the explicit Number conversion (faster and better than parseInt) so this also compiles in TypeScript.
Number

Deprecation warning: moment construction falls back to js Date (in html or ts) [duplicate]

I am using the following code to convert a server-side date-time to local time using moment.js.
moment(moment('Wed, 23 Apr 2014 09:54:51 +0000').format('lll')).fromNow()
But I am getting:
Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.
It seems I cannot get rid of it! How can I fix it?
To get rid of the warning, you need to either:
Pass in an ISO formatted version of your date string:
moment('2014-04-23T09:54:51');
Pass in the string you have now, but tell Moment what format the string is in:
moment('Wed, 23 Apr 2014 09:54:51 +0000', 'ddd, DD MMM YYYY HH:mm:ss ZZ');
Convert your string to a JavaScript Date object and then pass that into Moment:
moment(new Date('Wed, 23 Apr 2014 09:54:51 +0000'));
The last option is a built-in fallback that Moment supports for now, with the deprecated console warning. They say they won't support this fallback in future releases. They explain that using new Date('my date') is too unpredictable.
As an alternative, you can suppress showing the deprecation warning by setting moment.suppressDeprecationWarnings = true;
The date construction in moment internally uses the new Date() in the javascript. The new Date() construction recognizes the date string in either RFC2822 or ISO formats in all browsers. When constructing a moment object with date not in these formats, the deprecation warning is thrown.
Though the deprecation warnings are thrown, for some formats, the moment object will be successfully constructed in Chrome, but not in Firefox or Safari. Due to this, processing the date in Chrome may give results as expected(not all the time) and throws Invalid Date in others.
Consider, 02.02.2018,
Chrome - moment("02.02.2018")._d -> Fri Feb 02 2018 00:00:00 GMT+0530 (India Standard Time)
Firefox - moment("02.02.2018")._d -> Invalid Date
Safari - moment("02.02.2018")._d -> Invalid Date
So the moment.js is used at your own risk in case the recommended/standard formats are not used.
To suppress the deprecation warnings,
As suggested by #Joe Wilson in previous answer, give the date format on moment construction.
Example : moment("02.05.2018", "DD.MM.YYYY").format("DD MM YYYY");
Give the date in ISO or RFC2822 format.
Example : moment("2018-02-01T18:30:00.000Z") - ISO Format
moment("Thu, 01 Feb 2018 18:30:00 GMT") - RFC2822 Format - Format in Github
As suggested by #niutech in previous answer, set
moment.suppressDeprecationWarnings = true;
I suggest to overwrite the input fallback in moment.
moment.createFromInputFallback=function (config){
config._d = new Date(config._i);
}
As (3) will suppress all the warnings, (4) will suppress only the date construction fallback. Using (4), you will get Invalid Date as the internal new Date() is used and other deprecations can be seen in console, so moment can be upgraded or the deprecated methods can be replaced in the application.
If your date is passed to you from an API as string(like my issue), you can use a filter to convert the string to a date for moment. This will take care of the moment construction warning.
$scope.apiDate = 10/29/2017 18:28:03";
angular.module('myApp').filter('stringToDate', function() {
return function(value) {
return Date.parse(value);
};
});
Add it to the view:
{{apiDate | stringToDate | amDateFormat:'ddd, MMM DD'}}
In my case I was trying to generate a date time to include in my form data. But the format of the string I had access to looked like "10-Sep-2020 10:10" so when trying to use moment like
myDate = '10-Sep-2020 10:10';
moment(myDate).format('YYYY-MM-DD HH:mm:ss');
I got the deprecation warning. There is no problem using a string to create the date but you just have to let moment know what it is you are passing in. As in explicitly state the format it is about to receive, for example
moment(myDate, 'DD-MMM-YYYY HH:mm').format('YYYY-MM-DD HH:mm:ss');
result: 2020-09-10 10:10:00
That's it, the warning goes away, moment is happy and you have a date time format ready for persistence.
As indicated in the above answers. Providing the date format should work.
Why would I be getting the deprecation message with the following line of code. I thought the String + format was suppose to remedy the issue. moment.tz('2015:08:20 14:33:20', 'YYYY:MM:DD HH:mm:ss', 'America/New_York'). Also, please not I do not have control over the date format being provide. I know I can convert it myself to 'YYYY-MM-DDTHH:mm:ss' then moment does not show the deprecation message. However, according to the documentation, the line of code should work. Here is the deprecation message I am seeing.
"Deprecation warning: value provided is not in a recognized RFC2822 or
ISO format. moment construction falls back to js Date(), which is not
reliable across all browsers and versions. Non RFC2822/ISO date
formats are discouraged and will be removed in an upcoming major
release. Please refer to
http://momentjs.com/guides/#/warnings/js-date/ for more info."
Moment’s usage is so widespread that it’s impossible to deprecate the current version over time. Check out this post on alternative options Migrating away from moment.js

Get the given date format (the string specifying the format) in javascript or momentjs

Given a datestring, how can I get the format string describing that datestring?
Put another way, how can I get the format string that Date() or MomentJS (might be different for each, that's fine) would use to parse that datestring if one didn't pass an explicit format to use?
So given '2016-01-01' it should output something like 'YYYY-MM-DD', for example.
(I am aware this is a simple question and may have an answer somewhere, but it is difficult to word concisely, so I could only find questions and answers about how to parse datestrings or how to display dates. None about how to output the format itself.)
Consolidating information from Matt Johnson's answer, some comments, and my own contribution.
With Moment.js (version 2.10.7+), you can use the Creation Data API. Something like this in Node.js:
moment('2016-01-01 00:00:00').creationData().format
outputs
'YYYY-MM-DD HH:mm:ss'
Just as any date parsing is, there is ambiguity about the format of many datestrings due to things such as locale (the order of months and days are switched between the US and Europe, for example). But the above method is sufficient for me.
You can't, without having additional information, such as the locale. For example, 01/12/16 could be Jan 12, 2016, December 1, 2016, or December 16, 2001.
Even when you know the locale, there are several places in the real world where more than one date format is used, depending on context.
See https://en.wikipedia.org/wiki/Date_format_by_country
However, if you are just trying to determine which one of multiple known formats was used to parse the input string, moment has an API for that called Creation Data. For example:
var m = moment("2016/06/10", ["YYYY-MM-DD", "MM/DD/YYYY"], true);
var f = m.creationData().format; // "MM/DD/YYYY"

Javascript: parse a string to Date as LOCAL time zone

I have a string representing the current time: 2015-11-24T19:40:00. How do I parse this string in Javascript to get a Date represented by this string as the LOCAL TIME? Due to some restriction, I cannot use the library moment, but jquery is allowed. I know that someone has asked this question before, but the answer used moment
For example, if I run the script in California, then this string would represent 7PM pacific time, but if I run the script in NY then this string would represent Eastern Time?
I tried the following but Chrome and Firefox give me different results:
var str = "2015-11-24T19:40:00";
var date = new Date(str);
Chrome consumes it as UTC time (Tue Nov 24 2015 11:40:00 GMT-0800 (Pacific Standard Time)),
but Firefox consumes it as my local PACIFIC time (Tue Nov 24 2015 19:40:00 GMT-0800 (Pacific Standard Time))
I tried adding "Z" to str, like this var date = new Date(str+"Z");, then both browsers give me UTC time. Is there any similar letter to "Z" which tells all browsers (at least chrome, Firefox and Safari) to parse the string as local time zone?
Parsing of date strings using the Date constructor or Date.parse (which are essentially the same thing) is strongly recommended against.
If Date is called as a function and passed an ISO 8601 format date string without a timezone (such as 2015-11-24T19:40:00), you may get one of the following results:
Pre ES5 implementaitons may treat it as anything, even NaN (such as IE 8)
ES5 compliant implementations will treat it as UTC timezone
ECMAScript 2015 compliant implementations will treat it as local (which is consistent with ISO 8601)
A Date object has a time value which is UTC, and an offset based on system settings. When you send a Date to output, what you see is usually the result of Date.prototype.toString, which is an implementation dependent, human readable string representing the date and time, usually in a timezone based on system settings.
The best way to parse date strings is to do it manually. If you are assured that the format is consistent and valid, then parsing an ISO format string as a local date is as simple as:
/* #param {string} s - an ISO 8001 format date and time string
** with all components, e.g. 2015-11-24T19:40:00
** #returns {Date} - Date instance from parsing the string. May be NaN.
*/
function parseISOLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}
document.write(parseISOLocal('2015-11-24T19:40:00'));
Note that parsing of ISO strings using Date.parse only accepts UTC, it does not accept any other timezone designation (noting the above behaviour if it's missing).
A variation on RobG's terrific answer.
Note that this will require that you run bleeding edge JavaScript as
it relies on the arrow notation and spread operator.
function parseDateISOString(s) {
let ds = s.split(/\D/).map(s => parseInt(s));
ds[1] = ds[1] - 1; // adjust month
return new Date(...ds);
}
Note that this doesn't take into account if the date/time given is in any timezone. It will assume local time. You can change new Date for Date.UTC to assume UTC.
There are technical reasons for why you would write you code like this. For example, here we apply the correct number of arguments, with their corresponding expected type. It's true that the Date constructor will turn strings into numbers but what could be happening is that there's a deoptimization taking place where the optimized code is expecting a number but sees a string and takes a slower path. Not a big deal but I try to write my JavaScript to avoid such things. We also won't be indexing outside the bounds of the array if less than 6 components can be found in the string which is also one of those things you can do in JavaScript but it has subtle deoptimization caveats.
Where Date is called as a constructor with more than one argument, the specified arguments represent local time.
I also have a much faster way than using the string.split() because we already know where the numbers are:
return new Date(Number(date.substring(0, 4)), Number(date.substring(5, 7))-1,
Number(date.substring(8, 10)), Number(date.substring(11, 13)),
Number(date.substring(14, 16)), Number(date.substring(17, 19)));
This will work with and/or without the 'T' and 'Z' strings and still has decent performance. I added the explicit Number conversion (faster and better than parseInt) so this also compiles in TypeScript.
Number

What is the "right" JSON date format?

I've seen so many different standards for the JSON date format:
"\"\\/Date(1335205592410)\\/\"" .NET JavaScriptSerializer
"\"\\/Date(1335205592410-0500)\\/\"" .NET DataContractJsonSerializer
"2012-04-23T18:25:43.511Z" JavaScript built-in JSON object
"2012-04-21T18:25:43-05:00" ISO 8601
Which one is the right one? Or best? Is there any sort of standard on this?
JSON itself does not specify how dates should be represented, but JavaScript does.
You should use the format emitted by Date's toJSON method:
2012-04-23T18:25:43.511Z
Here's why:
It's human readable but also succinct
It sorts correctly
It includes fractional seconds, which can help re-establish chronology
It conforms to ISO 8601
ISO 8601 has been well-established internationally for more than a decade
ISO 8601 is endorsed by W3C, RFC3339, and XKCD
That being said, every date library ever written can understand "milliseconds since 1970". So for easy portability, ThiefMaster is right.
JSON does not know anything about dates. What .NET does is a non-standard hack/extension.
I would use a format that can be easily converted to a Date object in JavaScript, i.e. one that can be passed to new Date(...). The easiest and probably most portable format is the timestamp containing milliseconds since 1970.
There is no right format; The JSON specification does not specify a format for exchanging dates which is why there are so many different ways to do it.
The best format is arguably a date represented in ISO 8601 format (see Wikipedia); it is a well known and widely used format and can be handled across many different languages, making it very well suited for interoperability. If you have control over the generated json, for example, you provide data to other systems in json format, choosing 8601 as the date interchange format is a good choice.
If you do not have control over the generated json, for example, you are the consumer of json from several different existing systems, the best way of handling this is to have a date parsing utility function to handle the different formats expected.
When in doubt simply go to the javascript web console of a modern browser by pressing F12 (Ctrl+Shift+K in Firefox) and write the following:
new Date().toISOString()
Will output:
"2019-07-04T13:33:03.969Z"
Ta-da!!
From RFC 7493 (The I-JSON Message Format ):
I-JSON stands for either Internet JSON or Interoperable JSON, depending on who you ask.
Protocols often contain data items that are designed to contain
timestamps or time durations. It is RECOMMENDED that all such data
items be expressed as string values in ISO 8601 format, as specified
in RFC 3339, with the additional restrictions that uppercase rather
than lowercase letters be used, that the timezone be included not
defaulted, and that optional trailing seconds be included even when
their value is "00". It is also RECOMMENDED that all data items
containing time durations conform to the "duration" production in
Appendix A of RFC 3339, with the same additional restrictions.
Just for reference I've seen this format used:
Date.UTC(2017,2,22)
It works with JSONP which is supported by the $.getJSON() function. Not sure I would go so far as to recommend this approach... just throwing it out there as a possibility because people are doing it this way.
FWIW: Never use seconds since epoch in a communication protocol, nor milliseconds since epoch, because these are fraught with danger thanks to the randomized implementation of leap seconds (you have no idea whether sender and receiver both properly implement UTC leap seconds).
Kind of a pet hate, but many people believe that UTC is just the new name for GMT -- wrong! If your system does not implement leap seconds then you are using GMT (often called UTC despite being incorrect). If you do fully implement leap seconds you really are using UTC. Future leap seconds cannot be known; they get published by the IERS as necessary and require constant updates. If you are running a system that attempts to implement leap seconds but contains and out-of-date reference table (more common than you might think) then you have neither GMT, nor UTC, you have a wonky system pretending to be UTC.
These date counters are only compatible when expressed in a broken down format (y, m, d, etc). They are NEVER compatible in an epoch format. Keep that in mind.
"2014-01-01T23:28:56.782Z"
The date is represented in a standard and sortable format that represents a UTC time (indicated by the Z). ISO 8601 also supports time zones by replacing the Z with + or – value for the timezone offset:
"2014-02-01T09:28:56.321-10:00"
There are other variations of the timezone encoding in the ISO 8601 spec, but the –10:00 format is the only TZ format that current JSON parsers support. In general it’s best to use the UTC based format (Z) unless you have a specific need for figuring out the time zone in which the date was produced (possible only in server side generation).
NB:
var date = new Date();
console.log(date); // Wed Jan 01 2014 13:28:56 GMT-
1000 (Hawaiian Standard Time)
var json = JSON.stringify(date);
console.log(json); // "2014-01-01T23:28:56.782Z"
To tell you that's the preferred way even though JavaScript doesn't have a standard format for it
// JSON encoded date
var json = "\"2014-01-01T23:28:56.782Z\"";
var dateStr = JSON.parse(json);
console.log(dateStr); // 2014-01-01T23:28:56.782Z
JSON itself has no date format, it does not care how anyone stores dates. However, since this question is tagged with javascript, I assume you want to know how to store javascript dates in JSON. You can just pass in a date to the JSON.stringify method, and it will use Date.prototype.toJSON by default, which in turns uses Date.prototype.toISOString (MDN on Date.toJSON):
const json = JSON.stringify(new Date());
const parsed = JSON.parse(json); //2015-10-26T07:46:36.611Z
const date = new Date(parsed); // Back to date object
I also found it useful to use the reviver parameter of JSON.parse (MDN on JSON.parse) to automatically convert ISO strings back to javascript dates whenever I read JSON strings.
const isoDatePattern = new RegExp(/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/);
const obj = {
a: 'foo',
b: new Date(1500000000000) // Fri Jul 14 2017, etc...
}
const json = JSON.stringify(obj);
// Convert back, use reviver function:
const parsed = JSON.parse(json, (key, value) => {
if (typeof value === 'string' && value.match(isoDatePattern)){
return new Date(value); // isostring, so cast to js date
}
return value; // leave any other value as-is
});
console.log(parsed.b); // // Fri Jul 14 2017, etc...
The prefered way is using 2018-04-23T18:25:43.511Z...
The picture below shows why this is the prefered way:
So as you see Date has a native Method toJSON, which return in this format and can be easily converted to Date again...
In Sharepoint 2013, getting data in JSON there is no format to convert date into date only format, because in that date should be in ISO format
yourDate.substring(0,10)
This may be helpful for you
I believe that the best format for universal interoperability is not the ISO-8601 string, but rather the format used by EJSON:
{ "myDateField": { "$date" : <ms-since-epoch> } }
As described here: https://docs.meteor.com/api/ejson.html
Benefits
Parsing performance: If you store dates as ISO-8601 strings, this is great if you are expecting a date value under that particular field, but if you have a system which must determine value types without context, you're parsing every string for a date format.
No Need for Date Validation: You need not worry about validation and verification of the date. Even if a string matches ISO-8601 format, it may not be a real date; this can never happen with an EJSON date.
Unambiguous Type Declaration: as far as generic data systems go, if you wanted to store an ISO string as a string in one case, and a real system date in another, generic systems adopting the ISO-8601 string format will not allow this, mechanically (without escape tricks or similar awful solutions).
Conclusion
I understand that a human-readable format (ISO-8601 string) is helpful and more convenient for 80% of use cases, and indeed no-one should ever be told not to store their dates as ISO-8601 strings if that's what their applications understand, but for a universally accepted transport format which should guarantee certain values to for sure be dates, how can we allow for ambiguity and need for so much validation?
it is work for me with parse Server
{
"ContractID": "203-17-DC0101-00003-10011",
"Supplier":"Sample Co., Ltd",
"Value":12345.80,
"Curency":"USD",
"StartDate": {
"__type": "Date",
"iso": "2017-08-22T06:11:00.000Z"
}
}
There is only one correct answer to this and most systems get it wrong. Number of milliseconds since epoch, aka a 64 bit integer. Time Zone is a UI concern and has no business in the app layer or db layer. Why does your db care what time zone something is, when you know it's going to store it as a 64 bit integer then do the transformation calculations.
Strip out the extraneous bits and just treat dates as numbers up to the UI. You can use simple arithmetic operators to do queries and logic.
The following code has worked for me. This code will print date in DD-MM-YYYY format.
DateValue=DateValue.substring(6,8)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(0,4);
else, you can also use:
DateValue=DateValue.substring(0,4)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(6,8);
I think that really depends on the use case. In many cases it might be more beneficial to use a proper object model (instead of rendering the date to a string), like so:
{
"person" :
{
"name" : {
"first": "Tom",
"middle": "M",
...
}
"dob" : {
"year": 2012,
"month": 4,
"day": 23,
"hour": 18,
"minute": 25,
"second": 43,
"timeZone": "America/New_York"
}
}
}
Admittedly this is more verbose than RFC 3339 but:
it's human readable as well
it implements a proper object model (as in OOP, as far as JSON permits it)
it supports time zones (not just the UTC offset at the given date and time)
it can support smaller units like milliseconds, nanoseconds, ... or simply fractional seconds
it doesn't require a separate parsing step (to parse the date-time string), the JSON parser will do everything for you
easy creation with any date-time framework or implementation in any language
can easily be extended to support other calendar scales (Hebrew, Chinese, Islamic ...) and eras (AD, BC, ...)
it's year 10000 safe ;-) (RFC 3339 isn't)
supports all-day dates and floating times (Javascript's Date.toJSON() doesn't)
I don't think that correct sorting (as noted by funroll for RFC 3339) is a feature that's really needed when serializing a date to JSON. Also that's only true for date-times having the same time zone offset.

Categories