Show JavaScript date - datetimeoffset(7) in database - javascript

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");

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'))

How do I convert UTC/ GMT datetime to CST in Javascript? (not local, CST always)

I have a challenge where backend data is always stored in UTC time. Our front-end data is always presented in CST. I don't have access to this 'black box.'
I would like to mirror this in our data warehouse. Which is based in Europe (CET). So "local" conversion will not work.
I'm wondering the simplest, most straightforward way to accurately convert UTC time (I can have it in epoch milliseconds or a date format '2015-01-01 00:00:00') to Central Standard Time. (which is 5 or 6 hours behind based on Daylight Savings).
I see a lot of threads about converting to 'local' time ... again I don't want this, nor do I simply want to subtract 6 hours which will be wrong half the year.
Anyone have any ideas? This seems to be a very common problem but I've been searching for a while, and have found nothing.
Using moment.js with the moment-timezone add-on makes this task simple.
// construct a moment object with UTC-based input
var m = moment.utc('2015-01-01 00:00:00');
// convert using the TZDB identifier for US Central time
m.tz('America/Chicago');
// format output however you desire
var s = m.format("YYYY-MM-DD HH:mm:ss");
Additionally, since you are referring to the entire North American Central time zone, you should say either "Central Time", or "CT". The abbreviation "CST" as applied to North America explicitly means UTC-6, while the "CDT" abbreviation would be used for UTC-5 during daylight saving time.
Do be careful with abbreviations though. "CST" might mean "China Standard Time". (It actually has five different interpretations).
You can use the time zone offset to determine whether 5 or 6 hours should be subtracted.
var dateJan;
var dateJul;
var timezoneOffset;
var divUTC;
var divCST;
// Set initial date value
dateValue = new Date('10/31/2015 7:29:54 PM');
divUTC = document.getElementById('UTC_Time');
divCST = document.getElementById('CST_Time');
divUTC.innerHTML = 'from UTC = ' + dateValue.toString();
// Get dates for January and July
dateJan = new Date(dateValue.getFullYear(), 0, 1);
dateJul = new Date(dateValue.getFullYear(), 6, 1);
// Get timezone offset
timezoneOffset = Math.max(dateJan.getTimezoneOffset(), dateJul.getTimezoneOffset());
// Check if daylight savings
if (dateValue.getTimezoneOffset() < timezoneOffset) {
// Adjust date by 5 hours
dateValue = new Date(dateValue.getTime() - ((1 * 60 * 60 * 1000) * 5));
}
else {
// Adjust date by 6 hours
dateValue = new Date(dateValue.getTime() - ((1 * 60 * 60 * 1000) * 6));
}
divCST.innerHTML = 'to CST = ' + dateValue.toString();
<div id="UTC_Time"></div>
<br/>
<div id="CST_Time"></div>
Maybe you can use something like the following. Note, that is just an example you might need to adjust it to your needs.
let cstTime = new Date(createdAt).toLocaleString("es-MX", {
timeZone: "America/Mexico_City" });
You can use below code snippet for converting.
function convertUTCtoCDT() {
var timelagging = 6; // 5 or 6
var utc = new Date();
var cdt = new Date(utc.getTime()-((1 * 60 * 60 * 1000) * timelagging));
console.log("CDT: "+cdt);
}
let newDate = moment(new Date()).utc().format("YYYY-MM-DD HH:mm:ss").toString()
var m = moment.utc(newDate);
m.tz('America/Chicago');
var cstDate = m.format("YYYY-MM-DD HH:mm:ss");
You can use below code snippet
// Get time zone offset for CDT or CST
const getCdtCstOffset = () => {
const getNthSunday = (date, nth) => {
date.setDate((7*(nth-1))+(8-date.getDay()));
return date;
}
const isCdtTimezoneOffset = (today) => {
console.log('Today : ', today);
let dt = new Date();
var mar = new Date(dt.getFullYear(), 2, 1);
mar = getNthSunday(mar, 2);
console.log('CDT Start : ', mar);
var nov = new Date(dt.getFullYear(), 10, 1, 23, 59, 59);
nov = getNthSunday(nov, 1);
console.log('CDT End : ', nov);
return mar.getTime()< today.getTime() && nov.getTime()> today.getTime();
}
var today = new Date()// current date
if (isCdtTimezoneOffset(today)) {
return -5
} else {
return -6
}
}
let cstOrCdt = new Date();
cstOrCdt.setHours(cstOrCdt.getHours()+getCdtCstOffset())
console.log('CstOrCdt : ', cstOrCdt);

Javascript and mySQL dateTime stamp difference

I have a mySQL database in which I store the time in this format automatically:
2015-08-17 21:31:06
I am able to retrieve this time stamp from my database and bring it into javascript. I want to then get the current date time in javascript and determine how many days are between the current date time and the date time I pulled from the database.
I found this function when researching how to get the current date time in javascript:
Date();
But it seems to return the date in this format:
Tue Aug 18 2015 10:49:06 GMT-0700 (Pacific Daylight Time)
There has to be an easier way of doing this other than going character by character and picking it out from both?
You can build a new date in javascript by passing the data you receive from your backend as the first argument.
You have to make sure that the format is an accepted one. In your case we need to replace the space with a T. You may also be able to change the format from the back end.
Some good examples are available in the MDN docs.
var d = new Date("2015-08-17T21:31:06");
console.log(d.getMonth());
To calculate the difference in days you could do something like this:
var now = new Date();
var then = new Date("2015-08-15T21:31:06");
console.log((now - then)/1000/60/60/24);
You can select the difference directly in your query:
SELECT DATEDIFF(now(), myDateCol) FROM myTable;
the Date object has a function called getTime(), which will give you the current timestamp in milliseconds. You can then get the diff and convert to days by dividing by (1000 * 3600 * 24)
e.g.
var date1 = new Date()
var date2 = new Date()
var diffInMs = date2.getTime() - date1.getTime()
var diffInDays = diffInMs/(1000*3600*24)
Since none of the other answer got it quite right:
var pieces = "2015-08-17 21:31:06".split(' ');
var date = pieces[0].split('-');
var time = pieces[1].split(':');
var yr = date[0], mon = date[1], day = date[2];
var hour = time[0], min = time[1], sec = time[2];
var dateObj = new Date(yr, mon, day, hr, min, sec);
//if you want the fractional part, omit the call to Math.floor()
var diff = Math.floor((Date.now() - dateObj.getTime()) / (1000 * 60 * 60 * 24));
Note that none of this deals with the timezone difference between the browser and whatever you have stored in the DB. Here's an offset example:
var tzOff = new Date().getTimezoneOffset() * 60 * 1000; //in ms

Add future time to date and compare

I apologize if this question has been asked already but I couldn't find it for my problem.
I have seen this but am not sure what the number it returns represents: Date() * 1 * 10 * 1000
I'd like to set a future moment in time, and then compare it to the current instance of Date() to see which is greater. It could be a few seconds, a few minutes, a few hours or a few days in the future.
Here is the code that I have:
var futureMoment = new Date() * 1 *10 * 1000;
console.log('futureMoment = ' + futureMoment);
var currentMoment = new Date();
console.log('currentMoment = ' + currentMoment);
if ( currentMoment < futureMoment) {
console.log('currentMoment is less than futureMoment. item IS NOT expired yet');
}
else {
console.log('currentMoment is MORE than futureMoment. item IS expired');
}
Javascript date is based on the number of milliseconds since the Epoch (1 Jan 1970 00:00:00 UTC).
Therefore, to calculate a future date you add milliseconds.
var d = new Date();
var msecSinceEpoch = d.getTime(); // date now
var day = 24 * 60 * 60 * 1000; // 24hr * 60min * 60sec * 1000msec
var futureDate = new Date(msecSinceEpoc + day);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
var futureMoment = new Date() * 1 *10 * 1000;
becomes
var now = new Date();
var futureMoment = new Date(now.getTime() + 1 *10 * 1000);
I think you mean to add time. Not multiply it.
If you deal with time, there is a lot of tools to choose.
Try moment library.
Used following code to compare selected date time with current date time
var dt = "Thu Feb 04 2016 13:20:02 GMT+0530 (India Standard Time)"; //this date format will receive from input type "date"..
function compareIsPastDate(dt) {
var currDtObj = new Date();
var currentTime = currDtObj.getTime();
var enterDtObj = new Date(dt);
var enteredTime = enterDtObj.getTime();
return (currentTime > enteredTime);
}

Time between two times on current date

I am trying to calculate the time between two times on the current date using JavaScript. There are other questions similar to this one, but none seem to work, and few with many upvotes that I can find.
I have the following, which fails on the line: var diff = new Date(time1 - time2);, which always gives me an invalid Date when alerted, so it is clearly failing. I cannot work out why.
The initial date is added in the format of: hh:mm:ss in an input field. I am using jQuery.
$(function(){
$('#goTime').click(function(){
var currentDate = new Date();
var dateString = (strpad(currentDate.getDate()) +'-'+ strpad(currentDate.getMonth()+1)+'-'+currentDate.getFullYear()+' '+ $('#starttime').val());
var time1 = new Date(dateString).getTime();
var time2 = new Date().getTime();
var diff = new Date(time1 - time2);
var hours = diff.getHours();
var minutes = diff.getMinutes();
var seconds = diff.getMinutes();
alert(hours + ':' + minutes + ':' + seconds);
});
});
function strpad(val){
return (!isNaN(val) && val.toString().length==1)?"0"+val:val;
}
dateString is equal to: 14-01-2013 23:00
You have the fields in dateString backwards. Swap the year and day fields...
> new Date('14-01-2013 23:00')
Invalid Date
> new Date('2013-01-14 23:00')
Mon Jan 14 2013 23:00:00 GMT-0800 (PST)
dd-MM-yyyy HH:mm is not recognized as a valid time format by new Date(). You have a few options though:
Use slashes instead of dashes: dd/MM/yyyy HH:mm date strings are correctly parsed.
Use ISO date strings: yyyy-MM-dd HH:mm are also recognized.
Build the Date object yourself.
For the second option, since you only really care about the time, you could just split the time string yourself and pass them to Date.setHours(h, m, s):
var timeParts = $('#starttime').val().split(':', 2);
var time1 = new Date();
time1.setHours(timeParts[0], timeParts[1]);
You are experiencing an invalid time in your datestring. time1 is NaN, and so diff will be. It might be better to use this:
var date = new Date();
var match = /^(\d+):(\d+):(\d+)$/.exec($('#starttime').val()); // enforcing format
if (!match)
return alert("Invalid input!"); // abort
date.setHours(parseInt(match[1], 10));
date.setMinutes(parseInt(match[2], 10));
date.setSeconds(parseInt(match[3], 10));
var diff = Date.now() - date;
If you are trying to calculate the time difference between two dates, then you do not need to create a new date object to do that.
var time1 = new Date(dateString).getTime();
var time2 = new Date().getTime();
var diff = time1 - time2;// number of milliseconds
var seconds = diff/1000;
var minutes = seconds/60;
var hours = minutes/60;
Edit: You will want to take into account broofa's answer as well to
make sure your date string is correctly formatted
The getTime function returns the number of milliseconds since Jan 1, 1970. So by subtracting the two values you are left with the number of milliseconds between each date object. If you were to pass that value into the Date constructor, the resulting date object would not be what you are expecting. see getTime

Categories

Resources