Javascript date parsing YYYY-MM-DD HH:MM:SS T [duplicate] - javascript

This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 8 years ago.
I need to parse a string to date which comes in below format
2012-05-23 12:12:00-05:00
Date.parse("2012-05-23 12:12:00-05:00")
It is working fine with chorme but not in Firefox and IE. Any suggestions would be helpful.

I deleted my previous (less relevant) answer. This function should suit your purposes much better.
The key strategy is to get an absolute representation of your time without the time zone, and then adjust it backward or forward based on the specified timezone. What it spits out is a Date object in your browser's local time zone, but it will represent exactly the same moment in time as the string does.
Also, the format you specified isn't quite to spec, so the regex I wrote accepts your version as well as ISO8601.
Date.createFromString = function (string) {
'use strict';
var pattern = /^(\d\d\d\d)-(\d\d)-(\d\d)[ T](\d\d):(\d\d):(\d\d)([+-Z])(\d\d):(\d\d)$/;
var matches = pattern.exec(string);
if (!matches) {
throw new Error("Invalid string: " + string);
}
var year = matches[1];
var month = matches[2] - 1; // month counts from zero
var day = matches[3];
var hour = matches[4];
var minute = matches[5];
var second = matches[6];
var zoneType = matches[7];
var zoneHour = matches[8] || 0;
var zoneMinute = matches[9] || 0;
// Date.UTC() returns milliseconds since the unix epoch.
var absoluteMs = Date.UTC(year, month, day, hour, minute, second);
var ms;
if (zoneType === 'Z') {
// UTC time requested. No adjustment necessary.
ms = absoluteMs;
} else if (zoneType === '+') {
// Adjust UTC time by timezone offset
ms = absoluteMs - (zoneHour * 60 * 60 * 1000) - (zoneMinute * 60 * 1000);
} else if (zoneType === '-') {
// Adjust UTC time by timezone offset
ms = absoluteMs + (zoneHour * 60 * 60 * 1000) + (zoneMinute * 60 * 1000);
}
return new Date(ms);
};

Use moment.js's date parsing:
var date = moment("2012-05-23 12:12:00-05:00");
See http://momentjs.com/docs/#/parsing/string/

Related

Get timezone from date string in JavaScript

I'm working on a function that should check if a given dateString has the same timeZone as the browser timeZone. To get the browser timeZone I can use either a) Intl.DateTimeFormat().resolvedOptions().timeZone which will return Europe/Amsterdam for example or b) new Date().getTimeZoneOffset() that will return -60. Both are fine.
The tricky part is to get the timeZone from the dateString I want to pass, for example from: 2021-01-01T00:00:00-05:00 (which should be America/New_York or 300 AFAIK). How can I get the timeZone from that date? I tried to do: new Date('2021-01-01T00:00:00-05:00').getTimeZoneOffset() but that will convert it to the timeZone of my browser again, returning -60.
Example of function:
function isSameTimeZone(date) {
// function to get time zone here
const a = getTimeZone(date)
return a === new Date().getTimeZoneOffset() || Intl.DateTimeFormat().resolvedOptions().timeZone
}
Testcases
2021-01-01T00:00:00-08:00 (SF)
2021-01-01T00:00:00-05:00 (NY)
2021-01-01T00:00:00+05:30 (Mumbai)
2021-01-01T00:00:00+01:00 (Amsterdam)
Anyone out there with a solution? Thanks in advance!
Here's my method;
function checkTimezone(dateString) {
const testDate = new Date(dateString);
const dateRegex = /\d{4}-\d{2}-\d{2}/;
const myDate = new Date(testDate.toISOString().match(dateRegex)[0]);
return !(testDate - myDate);
}
const testCases = ['2021-01-01T00:00:00-05:00', '2021-01-01T00:00:00-08:00', '2021-01-01T00:00:00-05:00', '2021-01-01T00:00:00+05:30', '2021-01-01T00:00:00+01:00'];
testCases.forEach(testCase => console.log(checkTimezone(testCase)));
So here's how it works, you pass in your date string and create a new Date() instance with it.
Then I get the ISO string with the Date.ISOString() method and match it with the original string to get the date and create another Date instance from it without the time.
Then I find the difference (comes in milliseconds), and convert it to minutes
So I've been testing around a bit and in the end I came up with the following solution, based on the dates I provided in my question.
const getTimeZoneOffsetFromDate = date => {
/*
Check if the offset is positive or negative
e.g. +01:00 (Amsterdam) or -05:00 (New York)
*/
if (date.includes('+')) {
// Get the timezone hours
const timezone = date.split('+')[1]
// Get the hours
const hours = timezone.split(':')[0]
// Get the minutes (e.g. Mumbai has +05:30)
const minutes = timezone.split(':')[1]
/*
Amsterdam:
const offset = 01 * -60 = -60 + -0 = -60
*/
const offset = hours * -60 + parseInt(-minutes)
return offset === new Date().getTimezoneOffset()
}
// Repeat
const timezone = date.slice(date.length - 5)
const hours = timezone.split(':')[0]
const minutes = timezone.split(':')[1]
/*
New York:
const offset = 05 * 60 = 300 + 0 = 300
*/
const offset = hours * 60 + parseInt(minutes)
return offset === new Date().getTimezoneOffset()
}
console.log(getTimeZoneOffsetFromDate('2021-01-01T00:00:00+01:00'))

Check if time is falling under specific timeframe

I have a variable that stores a time value.
var cabtime = ["09:30:00"];
Variable time value is in 24-hour clock. That means 02:30:0PM will come as 14:30:00.
I want to check if the variable time falls under 08:00AM to 10:00AM window. If yes then I'll do an action.
Any pointers in this regard?
You could parse the time into seconds since midnight using:
var cabtime = ["HH:MM:SS"] // in 24hr time
function parseTime (string) {
parts = string.split(':').map(x => parseInt(x))
seconds = parts[0] * 3600 + parts[1] * 60 + parts[0]
return seconds
}
Then you can parse the time and the upper/lower bounds, and test using:
time = parseTime(cabtime[0])
lower = parseTime('08:00:00')
upper = parseTime('10:00:00')
if (time >= lower && time <= upper) {
print('Inside the range')
}
You can solve it easily by converting your strings to Date objects and compare them than.
var cabtime = ["09:30"];
function checkTimeRange(time, from, to, reldate) {
if (undefined === reldate) {
reldate = '0000T'; // the date the time strings are related to
}
let dtime = new Date(reldate + time);
let dfrom = new Date(reldate + from);
let dto = new Date(reldate + to);
return dfrom <= dtime && dtime <= dto;
}
checkTimeRange(cabtime[0], '08:00', '10:00'); // returns true
If you have full dates (e.g. '2019-07-25T09:30:00') instead of just the clock time you should provide for the parameter `reldate' an empty string.
* update: changed the wrong date format to standard format
* update: changed the date format again to be more fancy

Show JavaScript date - datetimeoffset(7) in database

The date is stored in the database as datetimeoffset(7).
The MVC controller gets the date from the database in the format "10/8/2015 6:05:12 PM -07:00" and passes it to the view as it is. I am trying to convert it to the correct date to show that in the view as mm/dd/yyy by doing the following:
var myDate = "10/8/2015 6:05:12 PM -07:00";
var newDate = New Date(myDate);
Then I'm formatting it to mm/dd/yyyy format after extracting the day, month and year.
IE11 and Safari do not like this and show error "Invalid date" in the console at the line
var newDate = New Date(myDate)
Chrome or Firefox doesn't show any problems.
Now I know that "10/8/2015 6:05:12 PM -07:00" is not a valid datestring. So my question is, how to handle this situation so all major browsers will show the correct date?
This function should work, I'm aware it needs some refactoring but it may be a good starting point.
function readDate(inputDate) {
// extract the date that can be parsed by IE ("10/8/2015 6:05:12 PM")
// and the timezone offset "-07:00"
var parsedDate = /([\s\S]*?)\s*([+-][0-9\:]+)$/.exec(inputDate);
//create new date with "datetimeoffset" string
var dt = new Date(parsedDate[1]);
// get millisecs
var localTime = dt.getTime();
// get the offset in millisecs
// notice the conversion to milliseconds
// the variable "localTzOffset" can be negative
// because the standar (http://www.w3.org/TR/NOTE-datetime)
var localTzOffset = dt.getTimezoneOffset() * 60 * 1000;
// to get UTC time
var utcTime = localTime + localTzOffset;
// extract hours and minutes difference
// for given timezone
var parsed = /([+-][0-9]+)\:([0-9]+)/.exec(parsedDate[2]);
var hours = parseInt(parsed[1]);
var minutes = parseInt(parsed[2]);
// convert extracted difference to milliseconds
var tzOffset = Math.abs(hours * 60 * 60 * 1000) + (minutes * 60 * 1000);
// taking into accout if negative
tzOffset = hours > 1 ? tzOffset : tzOffset * -1;
// construct the result Date
return new Date(utcTime + tzOffset);
}
Usage:
var date = readDate("10/8/2015 6:05:12 PM -07:00");

Compare 2 ISO 8601 timestamps and output seconds/minutes difference

I need to write JavaScript that's going to allow me to compare two ISO timestamps and then print out the difference between them, for example: "32 seconds".
Below is a function I found on Stack Overflow, it turns an ordinary date into an ISO formatted one. So, that's the first thing out the way, getting the current time in ISO format.
The next thing I need to do is get another ISO timestamp to compare it with, well, I have that stored in an object. It can be accessed like this: marker.timestamp (as shown in the code below). Now I need to compare those two two timestamps and work out the difference between them. If it's < 60 seconds, it should output in seconds, if it's > 60 seconds, it should output 1 minute and 12 seconds ago for example.
Thanks!
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var date = new Date();
var currentISODateTime = ISODateString(date);
var ISODateTimeToCompareWith = marker.timestamp;
// Now how do I compare them?
Comparing two dates is as simple as
var differenceInMs = dateNewer - dateOlder;
So, convert the timestamps back into Date instances
var d1 = new Date('2013-08-02T10:09:08Z'), // 10:09 to
d2 = new Date('2013-08-02T10:20:08Z'); // 10:20 is 11 mins
Get the difference
var diff = d2 - d1;
Format this as desired
if (diff > 60e3) console.log(
Math.floor(diff / 60e3), 'minutes ago'
);
else console.log(
Math.floor(diff / 1e3), 'seconds ago'
);
// 11 minutes ago
I would just store the Date object as part of your ISODate class. You can just do the string conversion when you need to display it, say in a toString method. That way you can just use very simple logic with the Date class to determine the difference between two ISODates:
var difference = ISODate.date - ISODateToCompare.date;
if (difference > 60000) {
// display minutes and seconds
} else {
// display seconds
}
I'd recommend getting the time in seconds from both timestamps, like this:
// currentISODateTime and ISODateTimeToCompareWith are ISO 8601 strings as defined in the original post
var firstDate = new Date(currentISODateTime),
secondDate = new Date(ISODateTimeToCompareWith),
firstDateInSeconds = firstDate.getTime() / 1000,
secondDateInSeconds = secondDate.getTime() / 1000,
difference = Math.abs(firstDateInSeconds - secondDateInSeconds);
And then working with the difference. For example:
if (difference < 60) {
alert(difference + ' seconds');
} else if (difference < 3600) {
alert(Math.floor(difference / 60) + ' minutes');
} else {
alert(Math.floor(difference / 3600) + ' hours');
}
Important: I used Math.abs to compare the dates in seconds to obtain the absolute difference between them, regardless of which is earlier.

JavaScript Time Until

I need to do the simplest thing, take an input date/time and write out the hours:minutes:seconds until that time. I haven't been able to figure it out. I even tried using Datejs which is great, but doesn't seem to have this functionality built in.
The time is going to be somewhere in the range of 0 mins -> 20 minutes
Thanks!
Don't bother with a library for something so simple. You must know the format of the input date string whether you use a library or not, so presuming ISO8601 (like 2013-02-08T08:34:15Z) you can do something like:
// Convert string in ISO8601 format to date object
// e.g. 2013-02-08T02:40:00Z
//
function isoToObj(s) {
var b = s.split(/[-TZ:]/i);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5]));
}
function timeToGo(s) {
// Utility to add leading zero
function z(n) {
return (n < 10? '0' : '') + n;
}
// Convert string to date object
var d = isoToObj(s);
var diff = d - new Date();
// Allow for previous times
var sign = diff < 0? '-' : '';
diff = Math.abs(diff);
// Get time components
var hours = diff/3.6e6 | 0;
var mins = diff%3.6e6 / 6e4 | 0;
var secs = Math.round(diff%6e4 / 1e3);
// Return formatted string
return sign + z(hours) + ':' + z(mins) + ':' + z(secs);
}
You may need to play with the function that converts the string to a date, but not much. You should be providing a UTC timestring anyway, unless you can be certain that the local time of the client is set to the timezone of the supplied datetime value.
Instead of Date.js, try Moment.js.

Categories

Resources