In angular I have to save data to database in this time format 20160422060933.0Z ?
Someone told me that this is Microsoft time format. I don't know how to convert date to this format, anyone encountered this before?
2016 is a year, 04 is a month, and 22 is a date but i don't know what 060933.0Z is. We use Dreamfactory API and SQL Server
Later edit: based on another answer, actually this seems to be a standard format colloquially called a "LDAP date". See Converting a ldap date for some details on the format (and how to parse it in Java). It can for sure be easily parsed with any typical JS date library or even without any library.
Let's break it down into pieces.
2016 = full year
04 = month, padded to 2 digits
22 = day of month, likely also padded to 2 digits
06 = hour of day, padded to 2 digits, likely on a 24h scale
09 = minute of the hour, padded to 2 digits
33 = second of the minute, likely padded to 2 digits
. = literal
0 = probably "second fraction"
Z = offset from UTC. Z meaning UTC.
Parsing it
You have several options to parse it:
If you assume you're going to always get an UTC datetime from the backend, you can naively parse it in JavaScript just by extracting the relevant substrings.
const input = '20160422060933.0Z';
new Date(Date.UTC(
input.substr(0, 4), // year
input.substr(4, 2) - 1, // month is 0-indexed
input.substr(6, 2), // day
input.substr(8, 2), // hour
input.substr(10, 2), // minute
input.substr(12, 2), // second
("0." + input.split(/[.Z]/gi)[1]) * 1000 // ms
));
// Fri Apr 22 2016 09:09:33 GMT+0300 (Eastern European Summer Time)
You can be a little creative and actually manipulate the string into an ISO format. Then you can just use the native Date.parse function, which supports parsing ISO strings (other formats are browser-dependent). The advantage is that it'll support dates that are not UTC as well.
new Date(Date.parse(
input.substr(0, 4) + "-" + // year, followed by minus
input.substr(4, 2) + "-" + // month, followed by minus
input.substr(6, 2) + "T" + // day, followed by minus
input.substr(8, 2) + ":" + // hour, followed by color
input.substr(10, 2) + ":" + // minute, followed by color
input.substr(12, 2) + // second
input.substr(14) // the rest of the string, which would include the fraction and offset.
))
// Fri Apr 22 2016 09:09:33 GMT+0300 (Eastern European Summer Time)
Use a library like luxon, momentjs, etc. This you might already have a JS library in your project. You'd need to build a date format pattern to parse this format into a native Date object or some other library-specific object. For example, with momentjs you'd do:
moment("20160422060933.0Z", "YYYYMMDDHHmmss.SZ")
// Fri Apr 22 2016 09:09:33 GMT+0300 (Eastern European Summer Time)
Formatting into it
This side of the operation is even simpler.
Without any date library, you just need to get rid of the "-", ":" and "T" separators from the ISO format. So you can just do the following:
new Date().toISOString().replace(/[:T-]/g, "")
// '20230209175305.421Z'
If you want to use a date library, then you just do the reverse, format operation using the same pattern as for parsing. Eg. in momentjs:
moment(new Date()).utc().format("YYYYMMDDHHmmss.S[Z]")
// "20230209175222.5Z"
(note that I needed to place the "Z" in brackets due to https://github.com/moment/moment-timezone/issues/213).
Just a side note to the other answer here:
You can use ldap2date npm package for parsing, should be not that "heavy" as moment.
Code:
import ldap2date from "ldap2date";
// or import { parse, toGeneralizedTime } from "ldap2date";
const dateString = "20160422060933.0Z";
const date = ldap2date.parse(dateString);
console.log(date.toUTCString());
// Fri, 22 Apr 2016 06:09:33 GMT
const str = ldap2date.toGeneralizedTime(date);
console.log(str);
// 20160422060933Z (note: no period.)
console.log(str.replace("Z", ".0Z"));
// 20160422060933.0Z
function getLdapString(date) {
return ldap2date.toGeneralizedTime(date);
}
const d = new Date();
console.log(getLdapString(d), d.toISOString());
// 20230209181603.965Z 2023-02-09T18:16:03.965Z
And some monkey-patching to match "format":
function getLdapString(date) {
return date.getMilliseconds() !== 0
? ldap2date.toGeneralizedTime(date)
: ldap2date.toGeneralizedTime(date).replace("Z", ".0Z");
}
const d = new Date();
d.setMilliseconds(15);
const d1 = new Date();
d1.setMilliseconds(0);
console.log("Date with milliseconds: ", d.toUTCString(), getLdapString(d));
console.log("Date without milliseconds: ", d1.toUTCString(), getLdapString(d1));
// Date with milliseconds: Thu, 09 Feb 2023 18:22:27 GMT 20230209182227.15Z
// Date without milliseconds: Thu, 09 Feb 2023 18:22:27 GMT 20230209182227.0Z
Or to ignore milliseconds part completelly
function getLdapString(date) {
const copy = new Date(date);
copy.setMilliseconds(0);
return ldap2date.toGeneralizedTime(copy).replace("Z", ".0Z");
}
console.log("Date with milliseconds: ", d.toUTCString(), getLdapString(d));
console.log("Date without milliseconds: ", d1.toUTCString(), getLdapString(d1));
// Date with milliseconds: Thu, 09 Feb 2023 18:29:50 GMT 20230209182950.0Z
// Date without milliseconds: Thu, 09 Feb 2023 18:29:50 GMT 20230209182950.0Z
Related
I'm calculating the dates for my application like date,week,month.
First I am defining day,week,month,custom like:
this.reportTypes = [{TypeId: 1, Type: 'Day'}, {TypeId: 6, Type: 'Week'}, {TypeId: 30, Type: 'Month'}, {
TypeId: 10,
Type: 'Custom'
}]
Next I'm defining dates like:
var currdate = new Date();
if(reportType==1){
// this.reportDataFromDate=currdate;
// this.reportDataToDate=currdate;
//This is for setting the current date
this.reportDataFromDate= currdate;
this.reportDataToDate= currdate;
}
else if(reportType==30){
var First = new Date(currdate.getFullYear(),currdate.getMonth(),1);
this.reportDataFromDate=First;
this.reportDataToDate=currdate;
}
else if(reportType!=10){
var last = new Date(currdate.getTime() - (reportType * 24 * 60 * 60 * 1000));
this.reportDataFromDate=last;
this.reportDataToDate=currdate;
}
}
The problem is after selecting reportType == 30 then it has to get the first day of the month.
It is showing the date as 1-Dec-2017 but it is getting the data of till 30th November 2017?
This is screenshot of the SQL server. I'm sending the date as 1st Dec 2017 but it is getting 30-11-2017.
When the Date() constructor is invoked with integers, the result is a date object with that date assumed your systems (read browser/os) timezone.
Example:
let d = new Date(2017);
// returns Thu Jan 01 1970 01:00:02 GMT+0100 (W. Europe Standard Time)
// and with d.toUTCString(): Fri, 30 Dec 2016 23:00:00 GMT
Which may end up in an entire different year when sending to the server
Using the string constructor and specifying timezone will help you overcome this.
Example:
let d = new Date('2017z');
// returns Sun Jan 01 2017 01:00:00 GMT+0100 (W. Europe Standard Time)
// and with d.toUTCString(): Sun, 01 Jan 2017 00:00:00 GMT
The latter which is what you should pass to a server, and normally do calculations on.
However, note that calculations with dates are a complicated matter best left to a library like moment.js. To get a feel of what you are dealing with have a look at this great talk from the WebRebel conference.
So to actually give an answer to your title, try this example which creates the date in a simple string using UTC:
let d = new Date(currdate.getUTCFullYear() + ' ' +(currdate.getUTCMonth() + 1) + ' 1z');
d.getUTCDay(); // returns the day as an integer where Monday is 0.
Note that we add 1 month due to getUTCMonth() returns January as 0.
Why the difference?
The new Date(x,y,z) constructor treats the parameters as local date values.
See MDB Web Docs - Date
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.
But, under the hood the date is stored as UTC (milliseconds since 1 Jan 1970).
const date = new Date(2017, 11, 29);
console.log('valueOf()', date.valueOf()) // 1514458800000
and the UTC date is different to your local date (see trailing 'Z' indicates UTC)
const date = new Date(2017, 11, 29);
console.log('date', date) // "2017-12-28T11:00:00.000Z" (trailing 'Z' means UTC)
// The difference in minutes between browser local and UTC
console.log('getTimezoneOffset()', date.getTimezoneOffset() )
and when you send it to the server, JSON sends it as UTC
const date = new Date(2017, 11, 29);
console.log('JSON', date.toJSON())
// JSON will yield string version of UTC === 2017-12-28T11:00:00.000Z
How to fix it
Well, you might decide that you actually want the date/time in local, and conclude it's not broken.
But if you want to send UTC to the server, wrap the parameters in Date.UTC()
const date = new Date(Date.UTC( 2017, 11, 29 ))
console.log('date.toJSON()', date.toJSON() ) // 2017-12-29T00:00:00.000Z
What about month parameter === 11?
From the MDB page referenced above,
Note: The argument month is 0-based. This means that January = 0 and December = 11.
If you are using .Net Web API as backend, you can config the timezone in Web API WebApiconfig.cs like below. It will serialize the time in UTC.
public static void Register(HttpConfiguration config)
{
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
}
Or use
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.RoundtripKind; //Time zone information should be preserved when converting.
Currently the input is "12 09 2016 00:00:00" and should assume it is in inputted as GMT date and time. But rather, it accepts it as local and converts it as such. And when it is turned to ISOString(), it converts it to GMT, and adds the time difference.
How can I take an input in "12 09 2016 00:00:00" format, take it as GMT/UTC, and do .toISOString() to turn it into the ISO format, "2016-12-09T00:00:00.000Z"?
var dateAndTime = new Date("12 09 2016 00:00:00")
//Returns: "Fri Dec 09 2016 00:00:00 GMT-0800 (PST)"
//Want it to return: "Fri Dec 09 2016 00:00:00 (GMT)"
var gmtDateAndTime = dateAndTime.toISOString();
//Returns: "2016-12-09T08:00:00.000Z"
//Want it to return: "2016-12-09T00:00:00.000Z"
Thank you and will be sure to vote up and accept the answer.
How can I take an input in "12 09 2016 00:00:00" format, take it as
GMT/UTC, and do .toISOString() to turn it into the ISO format,
"2016-12-09T00:00:00.000Z"?
It seems you just want to reformat the string, so just do that:
// Reformat string in MM DD YYYY HH:mm:ss format to
// ISO 8601 UTC
function formatDateStringISO(s) {
var b = s.split(/\D/);
return b[2] + '-' + b[0] + '-' + b[1] +
'T' + b[3] + ':' + b[4] + ':' + b[5] + '.000Z';
}
console.log(formatDateStringISO('12 09 2016 00:00:00'))
If you want to parse the string to a Date then output an ISO 8601 format string, do that:
// Parse string in MM DD YYYY HH:mm:ss format
// If date string is invalid, returns an invalid Date
function parseDateAsUTC(s) {
var b = s.split(/\D/);
var d = new Date(Date.UTC(b[2], --b[0], b[1], b[3], b[4], b[5]));
// Validate date
return d && d.getMonth() == b[0]? d : new Date(NaN);
}
// Valid date Invalid date
['12 09 2016 00:00:00', '12 34 2016 00:00:00'].forEach(function(s) {
var d = parseDateAsUTC(s);
console.log(s + ' => ' + d[isNaN(d)? 'toString' : 'toISOString']());
});
You need to use another Date constructor. The default constructor creates time in your local timezone.
Replace this:
var dateAndTime = new Date("12 09 2016 00:00:00")
With this:
var dateAndTime = new Date(Date.UTC(2016, 09, 12, 0, 0, 0));
If you can't convert your string ("12 09 2016 00:00:00") manually to the individual UTC parameters, you can use this (but unreliable especially in IE):
var utcDate = Date.parse("12 09 2016 00:00:00");
Do not use Date to parse happenstance date strings. Date.parse only works in a well defined manner when the input is an ISO8061 string.
From "15.9.4.2 Date.parse" in the ECMA 5 standard:
The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
and from 15.9.1.15 the string format recognized is
YYYY-MM-DDTHH:mm:ss.sssZ
which looks very much the ISO string you want to arrive at, not start with.
Alternative choices to solve the issue might include:
write your own function to parse a user input string. Has the problem that "12 09 2016" could mean "Dec 9 2016" or "Sep 12 2016" depending on user locale.
Use a date and time library. Moment.js is frequently mentioned in SO answers regarding such libraries.
Use the output of a date picker or validated data from a data base. Avoids issues with locale dependent formats.
Hard code conversion to ISO8061 format without parsing may be an option if the input string is absolutely guaranteed to be in "mm dd yyyy hh:mm:ss" format, as for example using
function isoFromZ( str) {
return str.substr(6,4) + "-" +
str.substr(0,2) + "-" +
str.substr(3,2) + "T" +
str.substring(11) + ".000Z";
}
In summary extract the UTC date and time components from a custom input string before creating a Date object. If extraction produced an ISO8061 date string it can be passed directly to the Date constructor as a parameter.
I'm having a javascript object as below.
var obj = { pageSize:"25",asOfDate:"Thu Sep 25 00:00:00 UTC+0530 2014"};
when i stringify it,
var d = JSON.stringify(obj);
its giving me result as
{"pageSize":"25","asOfDate":"2014-09-24T18:30:00Z"}
what could be the reason that its giving date 2014-09-24 than 2014-09-25 ?
EDIT:
My deployment server is located in US (Eastern Time UTC -5:00).when i check the site from my local machine in india its giving me date as 24 Sept 2014
UTC+0530 declares a UTC time offset. Seems that 5:30 is around the India or Sri Lanka area.
"2014-09-24T18:30:00Z" is the same as "Thu Sep 25 00:00:00 UTC+0530 2014" in two different formats. The Z in the first format is resolving to UTC (GMT) time, which in this case is -5:30. So 18:30 is 24:00 - 5:30.
So, if you are stringify-ing in a timezone that is negative offset (say in the United States UTC−08:00) then it could push the date back by one day when parsing.
I think this is what you are seeing.
Related SO Question: JSON Stringify changes time of date because of UTC
Try this
var obj = { pageSize:"25",asOfDate:"Thu Sep 25 00:00:00 UTC+0530 2014"};
obj.asOfDate = reverseUTC(obj.asOfDate);
var d = JSON.stringify(obj);
function reverseUTC(updatedDate) {
if ($.isEmptyObject(updatedDate)) {
var offset = updatedDate.getTimezoneOffset();
var currentDateTime = new Date();
updatedDate.setHours((currentDateTime.getHours() * 60 + currentDateTime.getMinutes() - offset) / 60);
updatedDate.setMinutes((currentDateTime.getHours() * 60 + currentDateTime.getMinutes() - offset) % 60);
return updatedDate;
}
}
There is no standard format for passing dates in JSON, so JSON.stringify is just calling the default date.prototype.toString() method and that is taking the timezone into account.
You need to ensure that the date is converted into a string to your particular requirements and only convert to JSON format.
I have a WCF service that serves some dates to my javascript. I want to manipulate the date, but it arrives in the javascript looking like this:
/Date(1361145600000+0000)/
I know this is the miliseconds since 1970/01/01, but I havent been able to figure out how to convert it to a javascript Date.
Do I need to use a regex or trim the text to extract the miliseconds, and then use it like this:
new Date(miliseconds)
Surely there must be an easier way?
If the '+0000' is a standard timezone offset, the first 2 digits are hours, the last two, minutes.
Presumably it is not always '0000'-
You need to add(or subtract) the milliseconds difference from UTC to the first integral part to return the correct Date.
function timeconvert(ds){
var D, dtime, T, tz, off,
dobj= ds.match(/(\d+)|([+-])|(\d{4})/g);
T= parseInt(dobj[0]);
tz= dobj[1];
off= dobj[2];
if(off){
off= (parseInt(off.substring(0, 2), 10)*3600000)+
(parseInt(off.substring(2), 10)*60000);
if(tz== '-') off*= -1;
}
else off= 0;
return new Date(T+= off).toUTCString();
}
timeconvert('Date(1361145600000)+0000');
//returned value: (String UTC)
Mon, 18 Feb 2013 00:00:00 GMT
If the Dates ARE always in UTC ('+0000') you can just pull the significant digits from the string-
function timeconvert(ds){
var d=ds.match(/(\d+)/)[1];
return new Date(+d).toUTCString();
}
timeconvert('Date(1361145600000)+0000)');
// returned value: (String UTC)
Mon, 18 Feb 2013 00:00:00 GMT
Code proposed by kennebec has a bug with a dates, that lower than 1 January 1970.
For example, Date(-124054000000+0300) is Wed Jan 26 1966 07:33:20
Fixed code :
http://output.jsbin.com/cejolu/3/edit?js,console
function timeconvert(ds){
var D, dtime, T, tz, off,
dobj = ds.match(/(-?\d+)|([+-])|(\d{4})/g);
T = parseInt(dobj[0], 10);
tz = dobj[1];
off = dobj[2];
if (off) {
off = (parseInt(off.substring(0, 2), 10) * 3600000) + (parseInt(off.substring(2), 10) * 60000);
if(tz == '-') off *= -1;
}
else off= 0;
return new Date(T += off).toUTCString();
}
Test for the newest changes :
console.log(timeconvert("Date(-124054000000+0300)"));
console.log(timeconvert('Date(1361145600000)+0000'));
console.log(timeconvert("Date(0+0300)"));
console.log(timeconvert("Date(-2+0200)"));
console.log(timeconvert("Date(-860000000000+1100)"));
/* Output */
"Wed, 26 Jan 1966 07:33:20 GMT"
"Mon, 18 Feb 2013 00:00:00 GMT"
"Thu, 01 Jan 1970 03:00:00 GMT"
"Thu, 01 Jan 1970 01:59:59 GMT"
"Thu, 01 Oct 1942 18:06:40 GMT"
You can create javascript dates using code such as:
var d = new Date("1/1/2012")
So it should be a matter of simply providing your .Net date as a format of:
new DateTime().ToString("M/d/yyyy")
I found another way of doing it, slightly adapted from kennebec's answer:
function timeConvert(date){
var miliseconds = date.replace(/(^.*\()|([+-].*$)/g, '');
miliseconds = parseInt(miliseconds);
return new Date(miliseconds);
}
var x = timeConvert("/Date(1361145600000+0000)/");
console.log(x);
How to parse a string into a date object at JavaScript (without using any 3d party) that is at dd-MM-yyyy HH:mm (all of them numbers) format?
var p = "04-22-1980 12:22".split(/-|\s+|:/);
// new Date(year, month, day [, hour, minute, second, millisecond ])
new Date(p[2], p[0] - 1, p[1], p[3], p[4]);
// => Tue Apr 22 1980 12:22:00 GMT-0500 (Central Daylight Time)
DateJS is your friend: http://www.datejs.com/
It parses pretty much anything reasonable you throw at it:
// Convert text into Date
Date.parse('today');
Date.parse('t + 5 d'); // today + 5 days
Date.parse('next thursday');
Date.parse('February 20th 1973');
Date.parse('Thu, 1 July 2004 22:30:00');
It's not perfect, but it does a pretty good job.