Converting to a Date Object from a datetime-local Element - javascript

I am using the HTML5 element datetime-local. I need to have two formats of the date. One as a date object the other as a string. I am going to store the date object in the database and I am going to use the string to set the datetime-local form input.
I need to convert this string to a date object:
"2014-06-22T16:01"
I can't seem to get the correct time. This is what I am getting. The time not correct.
Sun Jun 22 2014 09:01:00 GMT-0700 (PDT)
This is the how I am formating the date:
function formatTime(_date) {
var _this = this,
date = (_date) ? _date : new Date(),
day = date.getDate(),
month = date.getMonth() + 1,
year = date.getFullYear(),
hour = date.getHours(),
minute = date.getMinutes(),
seconds = date.getSeconds(),
function addZero(num) {
return num > 9 ? num : '0' + num;
}
minute = addZero(minute);
seconds = addZero(seconds);
hour = addZero(hour);
day = addZero(day);
month = addZero(month);
return year + '-' + month + '-' + day + 'T' + hour + ':' + minute;
};
Example:
http://codepen.io/zerostyle/pen/gwpuK/

If you are trying to get an ISO 8601 date string, you can try Date.prototype.toISOString. However, it always uses UTC. If you want to include the local timezone, use something like the following:
/* Return a string in ISO 8601 format with current timezone offset
** e.g. 2014-10-02T23:31:03+0800
** d is a Date object, or defaults to current Date if not supplied.
*/
function toLocalISOString(d) {
// Default to now if no date provided
d = d || new Date();
// Pad to two digits with leading zeros
function pad(n){
return (n<10?'0':'') + n;
}
// Pad to three digits with leading zeros
function padd(n){
return (n<100? '0' : '') + pad(n);
}
// Convert offset in mintues to +/-HHMM
// Note change of sign
// e.g. -600 => +1000, +330 => -0530
function minsToHHMM(n){
var sign = n<0? '-' : '+';
n = Math.abs(n);
var hh = pad(n/60 |0);
var mm = pad(n%60);
return sign + hh + mm;
}
var offset = minsToHHMM(d.getTimezoneOffset() * -1);
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) +
'T' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds()) +
'.' + padd(d.getMilliseconds()) + offset;
}
console.log(toLocalISOString(new Date())); // 2014-06-23T07:58:04.773+0800
Edit
The above probably misses your question, which seems to be;
I need to convert this string to a date object: "2014-06-22T16:01"
Presumaly you want to treat it as a local time string. ECMA-262 says that ISO–like strings without a timezone are to be treated as UTC, and that is what your host seems to be doing. So you need a function to create a local Date object from the string:
function parseYMDHM(s) {
var b = s.split(/\D+/);
return new Date(b[0], --b[1], b[2], b[3], b[4], b[5]||0, b[6]||0);
}
console.log(parseYMDHM('2014-06-22T16:01')); // Sun Jun 22 16:01:00 UTC+0800 2014

Related

JavaScript get this month's 1st date [duplicate]

Goal: Find the local time and UTC time offset then construct the URL in following format.
Example URL: /Actions/Sleep?duration=2002-10-10T12:00:00−05:00
The format is based on the W3C recommendation. The documentation says:
For example, 2002-10-10T12:00:00−05:00 (noon on 10 October 2002,
Central Daylight Savings Time as well as Eastern Standard Time in the U.S.)
is equal to 2002-10-10T17:00:00Z, five hours later than 2002-10-10T12:00:00Z.
So based on my understanding, I need to find my local time by new Date() then use getTimezoneOffset() function to compute the difference then attach it to the end of string.
Get local time with format
var local = new Date().format("yyyy-MM-ddThh:mm:ss"); // 2013-07-02T09:00:00
Get UTC time offset by hour
var offset = local.getTimezoneOffset() / 60; // 7
Construct URL (time part only)
var duration = local + "-" + offset + ":00"; // 2013-07-02T09:00:00-7:00
The above output means my local time is 2013/07/02 9am and difference from UTC is 7 hours (UTC is 7 hours ahead of local time)
So far it seems to work but what if getTimezoneOffset() returns negative value like -120?
I'm wondering how the format should look like in such case because I cannot figure out from W3C documentation.
Here's a simple helper function that will format JS dates for you.
function toIsoString(date) {
var tzo = -date.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function(num) {
return (num < 10 ? '0' : '') + num;
};
return date.getFullYear() +
'-' + pad(date.getMonth() + 1) +
'-' + pad(date.getDate()) +
'T' + pad(date.getHours()) +
':' + pad(date.getMinutes()) +
':' + pad(date.getSeconds()) +
dif + pad(Math.floor(Math.abs(tzo) / 60)) +
':' + pad(Math.abs(tzo) % 60);
}
var dt = new Date();
console.log(toIsoString(dt));
getTimezoneOffset() returns the opposite sign of the format required by the spec that you referenced.
This format is also known as ISO8601, or more precisely as RFC3339.
In this format, UTC is represented with a Z while all other formats are represented by an offset from UTC. The meaning is the same as JavaScript's, but the order of subtraction is inverted, so the result carries the opposite sign.
Also, there is no method on the native Date object called format, so your function in #1 will fail unless you are using a library to achieve this. Refer to this documentation.
If you are seeking a library that can work with this format directly, I recommend trying moment.js. In fact, this is the default format, so you can simply do this:
var m = moment(); // get "now" as a moment
var s = m.format(); // the ISO format is the default so no parameters are needed
// sample output: 2013-07-01T17:55:13-07:00
This is a well-tested, cross-browser solution, and has many other useful features.
I think it is worth considering that you can get the requested info with just a single API call to the standard library...
new Date().toLocaleString( 'sv', { timeZoneName: 'short' } );
// produces "2019-10-30 15:33:47 GMT−4"
You would have to do text swapping if you want to add the 'T' delimiter, remove the 'GMT-', or append the ':00' to the end.
But then you can easily play with the other options if you want to eg. use 12h time or omit the seconds etc.
Note that I'm using Sweden as locale because it is one of the countries that uses ISO 8601 format. I think most of the ISO countries use this 'GMT-4' format for the timezone offset other then Canada which uses the time zone abbreviation eg. "EDT" for eastern-daylight-time.
You can get the same thing from the newer standard i18n function "Intl.DateTimeFormat()"
but you have to tell it to include the time via the options or it will just give date.
My answer is a slight variation for those who just want today's date in the local timezone in the YYYY-MM-DD format.
Let me be clear:
My Goal: get today's date in the user's timezone but formatted as ISO8601 (YYYY-MM-DD)
Here is the code:
new Date().toLocaleDateString("sv") // "2020-02-23" //
This works because the Sweden locale uses the ISO 8601 format.
This is my function for the clients timezone, it's lite weight and simple
function getCurrentDateTimeMySql() {
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
var mySqlDT = localISOTime;
return mySqlDT;
}
Check this:
function dateToLocalISO(date) {
const off = date.getTimezoneOffset()
const absoff = Math.abs(off)
return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) +
(off > 0 ? '-' : '+') +
Math.floor(absoff / 60).toFixed(0).padStart(2,'0') + ':' +
(absoff % 60).toString().padStart(2,'0'))
}
// Test it:
d = new Date()
dateToLocalISO(d)
// ==> '2019-06-21T16:07:22.181-03:00'
// Is similar to:
moment = require('moment')
moment(d).format('YYYY-MM-DDTHH:mm:ss.SSSZ')
// ==> '2019-06-21T16:07:22.181-03:00'
You can achieve this with a few simple extension methods. The following Date extension method returns just the timezone component in ISO format, then you can define another for the date/time part and combine them for a complete date-time-offset string.
Date.prototype.getISOTimezoneOffset = function () {
const offset = this.getTimezoneOffset();
return (offset < 0 ? "+" : "-") + Math.floor(Math.abs(offset / 60)).leftPad(2) + ":" + (Math.abs(offset % 60)).leftPad(2);
}
Date.prototype.toISOLocaleString = function () {
return this.getFullYear() + "-" + (this.getMonth() + 1).leftPad(2) + "-" +
this.getDate().leftPad(2) + "T" + this.getHours().leftPad(2) + ":" +
this.getMinutes().leftPad(2) + ":" + this.getSeconds().leftPad(2) + "." +
this.getMilliseconds().leftPad(3);
}
Number.prototype.leftPad = function (size) {
var s = String(this);
while (s.length < (size || 2)) {
s = "0" + s;
}
return s;
}
Example usage:
var date = new Date();
console.log(date.toISOLocaleString() + date.getISOTimezoneOffset());
// Prints "2020-08-05T16:15:46.525+10:00"
I know it's 2020 and most people are probably using Moment.js by now, but a simple copy & pastable solution is still sometimes handy to have.
(The reason I split the date/time and offset methods is because I'm using an old Datejs library which already provides a flexible toString method with custom format specifiers, but just doesn't include the timezone offset. Hence, I added toISOLocaleString for anyone without said library.)
Just my two cents here
I was facing this issue with datetimes so what I did is this:
const moment = require('moment-timezone')
const date = moment.tz('America/Bogota').format()
Then save date to db to be able to compare it from some query.
To install moment-timezone
npm i moment-timezone
No moment.js needed: Here's a full round trip answer, from an input type of "datetime-local" which outputs an ISOLocal string to UTCseconds at GMT and back:
<input type="datetime-local" value="2020-02-16T19:30">
isoLocal="2020-02-16T19:30"
utcSeconds=new Date(isoLocal).getTime()/1000
//here you have 1581899400 for utcSeconds
let isoLocal=new Date(utcSeconds*1000-new Date().getTimezoneOffset()*60000).toISOString().substring(0,16)
2020-02-16T19:30
date to ISO string,
with local(computer) time zone,
with or without milliseconds
ISO ref: https://en.wikipedia.org/wiki/ISO_8601
how to use: toIsoLocalTime(new Date())
function toIsoLocalTime(value) {
if (value instanceof Date === false)
value = new Date();
const off = value.getTimezoneOffset() * -1;
const del = value.getMilliseconds() ? 'Z' : '.'; // have milliseconds ?
value = new Date(value.getTime() + off * 60000); // add or subtract time zone
return value
.toISOString()
.split(del)[0]
+ (off < 0 ? '-' : '+')
+ ('0' + Math.abs(Math.floor(off / 60))).substr(-2)
+ ':'
+ ('0' + Math.abs(off % 60)).substr(-2);
}
function test(value) {
const event = new Date(value);
console.info(value + ' -> ' + toIsoLocalTime(event) + ', test = ' + (event.getTime() === (new Date(toIsoLocalTime(event))).getTime() ));
}
test('2017-06-14T10:00:00+03:00'); // test with timezone
test('2017-06-14T10:00:00'); // test with local timezone
test('2017-06-14T10:00:00Z'); // test with UTC format
test('2099-12-31T23:59:59.999Z'); // date with milliseconds
test((new Date()).toString()); // now
consider using moment (like Matt's answer).
From version 2.20.0, you may call .toISOString(true) to prevent UTC conversion:
console.log(moment().toISOString(true));
// sample output: 2022-04-06T16:26:36.758+03:00
Use Temporal.
Temporal.Now.zonedDateTimeISO().toString()
// '2022-08-09T14:16:47.762797591-07:00[America/Los_Angeles]'
To omit the fractional seconds and IANA time zone:
Temporal.Now.zonedDateTimeISO().toString({
timeZoneName: "never",
fractionalSecondDigits: 0
})
// '2022-08-09T14:18:34-07:00'
Note: Temporal is currently (2022) available as a polyfill, but will soon be available in major browsers.
With luxon:
DateTime.now().toISODate() // 2022-05-23
Here are the functions I used for this end:
function localToGMTStingTime(localTime = null) {
var date = localTime ? new Date(localTime) : new Date();
return new Date(date.getTime() + (date.getTimezoneOffset() * 60000)).toISOString();
};
function GMTToLocalStingTime(GMTTime = null) {
var date = GMTTime ? new Date(GMTTime) : new Date();;
return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString();
};
let myDate = new Date(dateToBeFormatted * 1000); // depends if you have milliseconds, or seconds, then the * 1000 might be not, or required.
timeOffset = myDate.getTimezoneOffset();
myDate = new Date(myDate.getTime() - (timeOffset * 60 * 1000));
console.log(myDate.toISOString().split('T')[0]);
Inspired by https://stackoverflow.com/a/29774197/11127383, including timezone offset comment.
a simple way to get:
//using a sample date
let iso_str = '2022-06-11T01:51:59.618Z';
let d = new Date(iso_str);
let tz = 'America/Santiago'
let options = {
timeZone:tz ,
timeZoneName:'longOffset',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
fractionalSecondDigits: 3
}
str_locale = d.toLocaleString("sv-SE",options);
iso_str_tz = str_locale.replace(/(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2}),(\d+)\s+/,'$1-$2-$3T$4:$5:$6.$7').replace('GMT−', '-' ).replace('GMT+','+')
console.log('iso_str : ',iso_str);
console.log('str_locale : ',str_locale);
console.log('iso_str_tz : ',iso_str_tz);
console.log('iso_str_tz --> date : ',new Date(iso_str_tz));
console.log('iso_str_tz --> iso_str: ',new Date(iso_str_tz).toISOString());
Using moment.js, you can use keepOffset parameter of toISOString:
toISOString(keepOffset?: boolean): string;
moment().toISOString(true)
Alternative approach with dayjs
import dayjs from "dayjs"
const formattedDateTime = dayjs(new Date()).format()
console.log(formattedDateTime) // Prints 2022-11-09T07:49:29+03:00
Here's another way a convert your date with an offset.
function toCustomDateString(date, offset) {
function pad(number) {
if (number < 10) {
return "0" + number;
}
return number;
}
var offsetHours = offset / 60;
var offsetMinutes = offset % 60;
var sign = (offset > 0) ? "+" : "-";
offsetHours = pad(Math.floor(Math.abs(offsetHours)));
offsetMinutes = pad(Math.abs(offsetMinutes));
return date.getFullYear() +
"-" + pad(date.getMonth() + 1) +
"-" + pad(date.getDate()) +
"T" + pad(date.getHours()) +
":" + pad(date.getMinutes()) +
":" + pad(date.getSeconds()) +
sign + offsetHours +
":" + offsetMinutes;
}
Then you can use it like this:
var date = new Date();
var offset = 330; // offset in minutes from UTC, for India it is 330 minutes ahead of UTC
var customDateString = toCustomDateString(date, offset);
console.log(customDateString);
// Output: "2023-02-09T10:29:31+05:30"
function setDate(){
var now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
var timeToSet = now.toISOString().slice(0,16);
/*
If you have an element called "eventDate" like the following:
<input type="datetime-local" name="eventdate" id="eventdate" />
and you would like to set the current and minimum time then use the following:
*/
var elem = document.getElementById("eventDate");
elem.value = timeToSet;
elem.min = timeToSet;
}
I found another more easy solution:
let now = new Date();
// correct time zone offset for generating iso string
now.setMinutes(now.getMinutes() - now.getTimezoneOffset())
now = now.toISOString();
I undo the timezone offset by substracting it from the current date object.
The UTC time from the date object is now pointing to the local time.
That gives you the possibility to get the iso date for the local time.

Get the hour shown in an ISOstring with an offset [duplicate]

Goal: Find the local time and UTC time offset then construct the URL in following format.
Example URL: /Actions/Sleep?duration=2002-10-10T12:00:00−05:00
The format is based on the W3C recommendation. The documentation says:
For example, 2002-10-10T12:00:00−05:00 (noon on 10 October 2002,
Central Daylight Savings Time as well as Eastern Standard Time in the U.S.)
is equal to 2002-10-10T17:00:00Z, five hours later than 2002-10-10T12:00:00Z.
So based on my understanding, I need to find my local time by new Date() then use getTimezoneOffset() function to compute the difference then attach it to the end of string.
Get local time with format
var local = new Date().format("yyyy-MM-ddThh:mm:ss"); // 2013-07-02T09:00:00
Get UTC time offset by hour
var offset = local.getTimezoneOffset() / 60; // 7
Construct URL (time part only)
var duration = local + "-" + offset + ":00"; // 2013-07-02T09:00:00-7:00
The above output means my local time is 2013/07/02 9am and difference from UTC is 7 hours (UTC is 7 hours ahead of local time)
So far it seems to work but what if getTimezoneOffset() returns negative value like -120?
I'm wondering how the format should look like in such case because I cannot figure out from W3C documentation.
Here's a simple helper function that will format JS dates for you.
function toIsoString(date) {
var tzo = -date.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function(num) {
return (num < 10 ? '0' : '') + num;
};
return date.getFullYear() +
'-' + pad(date.getMonth() + 1) +
'-' + pad(date.getDate()) +
'T' + pad(date.getHours()) +
':' + pad(date.getMinutes()) +
':' + pad(date.getSeconds()) +
dif + pad(Math.floor(Math.abs(tzo) / 60)) +
':' + pad(Math.abs(tzo) % 60);
}
var dt = new Date();
console.log(toIsoString(dt));
getTimezoneOffset() returns the opposite sign of the format required by the spec that you referenced.
This format is also known as ISO8601, or more precisely as RFC3339.
In this format, UTC is represented with a Z while all other formats are represented by an offset from UTC. The meaning is the same as JavaScript's, but the order of subtraction is inverted, so the result carries the opposite sign.
Also, there is no method on the native Date object called format, so your function in #1 will fail unless you are using a library to achieve this. Refer to this documentation.
If you are seeking a library that can work with this format directly, I recommend trying moment.js. In fact, this is the default format, so you can simply do this:
var m = moment(); // get "now" as a moment
var s = m.format(); // the ISO format is the default so no parameters are needed
// sample output: 2013-07-01T17:55:13-07:00
This is a well-tested, cross-browser solution, and has many other useful features.
I think it is worth considering that you can get the requested info with just a single API call to the standard library...
new Date().toLocaleString( 'sv', { timeZoneName: 'short' } );
// produces "2019-10-30 15:33:47 GMT−4"
You would have to do text swapping if you want to add the 'T' delimiter, remove the 'GMT-', or append the ':00' to the end.
But then you can easily play with the other options if you want to eg. use 12h time or omit the seconds etc.
Note that I'm using Sweden as locale because it is one of the countries that uses ISO 8601 format. I think most of the ISO countries use this 'GMT-4' format for the timezone offset other then Canada which uses the time zone abbreviation eg. "EDT" for eastern-daylight-time.
You can get the same thing from the newer standard i18n function "Intl.DateTimeFormat()"
but you have to tell it to include the time via the options or it will just give date.
My answer is a slight variation for those who just want today's date in the local timezone in the YYYY-MM-DD format.
Let me be clear:
My Goal: get today's date in the user's timezone but formatted as ISO8601 (YYYY-MM-DD)
Here is the code:
new Date().toLocaleDateString("sv") // "2020-02-23" //
This works because the Sweden locale uses the ISO 8601 format.
This is my function for the clients timezone, it's lite weight and simple
function getCurrentDateTimeMySql() {
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
var mySqlDT = localISOTime;
return mySqlDT;
}
Check this:
function dateToLocalISO(date) {
const off = date.getTimezoneOffset()
const absoff = Math.abs(off)
return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) +
(off > 0 ? '-' : '+') +
Math.floor(absoff / 60).toFixed(0).padStart(2,'0') + ':' +
(absoff % 60).toString().padStart(2,'0'))
}
// Test it:
d = new Date()
dateToLocalISO(d)
// ==> '2019-06-21T16:07:22.181-03:00'
// Is similar to:
moment = require('moment')
moment(d).format('YYYY-MM-DDTHH:mm:ss.SSSZ')
// ==> '2019-06-21T16:07:22.181-03:00'
You can achieve this with a few simple extension methods. The following Date extension method returns just the timezone component in ISO format, then you can define another for the date/time part and combine them for a complete date-time-offset string.
Date.prototype.getISOTimezoneOffset = function () {
const offset = this.getTimezoneOffset();
return (offset < 0 ? "+" : "-") + Math.floor(Math.abs(offset / 60)).leftPad(2) + ":" + (Math.abs(offset % 60)).leftPad(2);
}
Date.prototype.toISOLocaleString = function () {
return this.getFullYear() + "-" + (this.getMonth() + 1).leftPad(2) + "-" +
this.getDate().leftPad(2) + "T" + this.getHours().leftPad(2) + ":" +
this.getMinutes().leftPad(2) + ":" + this.getSeconds().leftPad(2) + "." +
this.getMilliseconds().leftPad(3);
}
Number.prototype.leftPad = function (size) {
var s = String(this);
while (s.length < (size || 2)) {
s = "0" + s;
}
return s;
}
Example usage:
var date = new Date();
console.log(date.toISOLocaleString() + date.getISOTimezoneOffset());
// Prints "2020-08-05T16:15:46.525+10:00"
I know it's 2020 and most people are probably using Moment.js by now, but a simple copy & pastable solution is still sometimes handy to have.
(The reason I split the date/time and offset methods is because I'm using an old Datejs library which already provides a flexible toString method with custom format specifiers, but just doesn't include the timezone offset. Hence, I added toISOLocaleString for anyone without said library.)
Just my two cents here
I was facing this issue with datetimes so what I did is this:
const moment = require('moment-timezone')
const date = moment.tz('America/Bogota').format()
Then save date to db to be able to compare it from some query.
To install moment-timezone
npm i moment-timezone
No moment.js needed: Here's a full round trip answer, from an input type of "datetime-local" which outputs an ISOLocal string to UTCseconds at GMT and back:
<input type="datetime-local" value="2020-02-16T19:30">
isoLocal="2020-02-16T19:30"
utcSeconds=new Date(isoLocal).getTime()/1000
//here you have 1581899400 for utcSeconds
let isoLocal=new Date(utcSeconds*1000-new Date().getTimezoneOffset()*60000).toISOString().substring(0,16)
2020-02-16T19:30
date to ISO string,
with local(computer) time zone,
with or without milliseconds
ISO ref: https://en.wikipedia.org/wiki/ISO_8601
how to use: toIsoLocalTime(new Date())
function toIsoLocalTime(value) {
if (value instanceof Date === false)
value = new Date();
const off = value.getTimezoneOffset() * -1;
const del = value.getMilliseconds() ? 'Z' : '.'; // have milliseconds ?
value = new Date(value.getTime() + off * 60000); // add or subtract time zone
return value
.toISOString()
.split(del)[0]
+ (off < 0 ? '-' : '+')
+ ('0' + Math.abs(Math.floor(off / 60))).substr(-2)
+ ':'
+ ('0' + Math.abs(off % 60)).substr(-2);
}
function test(value) {
const event = new Date(value);
console.info(value + ' -> ' + toIsoLocalTime(event) + ', test = ' + (event.getTime() === (new Date(toIsoLocalTime(event))).getTime() ));
}
test('2017-06-14T10:00:00+03:00'); // test with timezone
test('2017-06-14T10:00:00'); // test with local timezone
test('2017-06-14T10:00:00Z'); // test with UTC format
test('2099-12-31T23:59:59.999Z'); // date with milliseconds
test((new Date()).toString()); // now
consider using moment (like Matt's answer).
From version 2.20.0, you may call .toISOString(true) to prevent UTC conversion:
console.log(moment().toISOString(true));
// sample output: 2022-04-06T16:26:36.758+03:00
Use Temporal.
Temporal.Now.zonedDateTimeISO().toString()
// '2022-08-09T14:16:47.762797591-07:00[America/Los_Angeles]'
To omit the fractional seconds and IANA time zone:
Temporal.Now.zonedDateTimeISO().toString({
timeZoneName: "never",
fractionalSecondDigits: 0
})
// '2022-08-09T14:18:34-07:00'
Note: Temporal is currently (2022) available as a polyfill, but will soon be available in major browsers.
With luxon:
DateTime.now().toISODate() // 2022-05-23
Here are the functions I used for this end:
function localToGMTStingTime(localTime = null) {
var date = localTime ? new Date(localTime) : new Date();
return new Date(date.getTime() + (date.getTimezoneOffset() * 60000)).toISOString();
};
function GMTToLocalStingTime(GMTTime = null) {
var date = GMTTime ? new Date(GMTTime) : new Date();;
return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString();
};
let myDate = new Date(dateToBeFormatted * 1000); // depends if you have milliseconds, or seconds, then the * 1000 might be not, or required.
timeOffset = myDate.getTimezoneOffset();
myDate = new Date(myDate.getTime() - (timeOffset * 60 * 1000));
console.log(myDate.toISOString().split('T')[0]);
Inspired by https://stackoverflow.com/a/29774197/11127383, including timezone offset comment.
a simple way to get:
//using a sample date
let iso_str = '2022-06-11T01:51:59.618Z';
let d = new Date(iso_str);
let tz = 'America/Santiago'
let options = {
timeZone:tz ,
timeZoneName:'longOffset',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
fractionalSecondDigits: 3
}
str_locale = d.toLocaleString("sv-SE",options);
iso_str_tz = str_locale.replace(/(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2}),(\d+)\s+/,'$1-$2-$3T$4:$5:$6.$7').replace('GMT−', '-' ).replace('GMT+','+')
console.log('iso_str : ',iso_str);
console.log('str_locale : ',str_locale);
console.log('iso_str_tz : ',iso_str_tz);
console.log('iso_str_tz --> date : ',new Date(iso_str_tz));
console.log('iso_str_tz --> iso_str: ',new Date(iso_str_tz).toISOString());
Using moment.js, you can use keepOffset parameter of toISOString:
toISOString(keepOffset?: boolean): string;
moment().toISOString(true)
Alternative approach with dayjs
import dayjs from "dayjs"
const formattedDateTime = dayjs(new Date()).format()
console.log(formattedDateTime) // Prints 2022-11-09T07:49:29+03:00
Here's another way a convert your date with an offset.
function toCustomDateString(date, offset) {
function pad(number) {
if (number < 10) {
return "0" + number;
}
return number;
}
var offsetHours = offset / 60;
var offsetMinutes = offset % 60;
var sign = (offset > 0) ? "+" : "-";
offsetHours = pad(Math.floor(Math.abs(offsetHours)));
offsetMinutes = pad(Math.abs(offsetMinutes));
return date.getFullYear() +
"-" + pad(date.getMonth() + 1) +
"-" + pad(date.getDate()) +
"T" + pad(date.getHours()) +
":" + pad(date.getMinutes()) +
":" + pad(date.getSeconds()) +
sign + offsetHours +
":" + offsetMinutes;
}
Then you can use it like this:
var date = new Date();
var offset = 330; // offset in minutes from UTC, for India it is 330 minutes ahead of UTC
var customDateString = toCustomDateString(date, offset);
console.log(customDateString);
// Output: "2023-02-09T10:29:31+05:30"
function setDate(){
var now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
var timeToSet = now.toISOString().slice(0,16);
/*
If you have an element called "eventDate" like the following:
<input type="datetime-local" name="eventdate" id="eventdate" />
and you would like to set the current and minimum time then use the following:
*/
var elem = document.getElementById("eventDate");
elem.value = timeToSet;
elem.min = timeToSet;
}
I found another more easy solution:
let now = new Date();
// correct time zone offset for generating iso string
now.setMinutes(now.getMinutes() - now.getTimezoneOffset())
now = now.toISOString();
I undo the timezone offset by substracting it from the current date object.
The UTC time from the date object is now pointing to the local time.
That gives you the possibility to get the iso date for the local time.

Convert date with full month name and time to ISO date

I have a date and time stamp in the format 02 December 2016 18:00pm.
This is generated by jQuery selector:
"datestamp": $('span.article_info__published').text(),
How can I convert it to the format 2007-07-24T12:50:00+01:00?
If possible, I'd like to do it on the same line. Otherwise it needs to accommodate this sort of construction...
result = {
"other": $('div.article__header h1').text(),
"datestamp": $('span.article_info__published').text(),
"more": $('meta[name="twitter:image"]').attr("content"),
"assorted": $('figcaption.caption').text(),
};
(I can't remember the name of the destination format... I think ISO 8601?)
Update: the following returns "invalid date"...
var myDate = new Date("02 December 2016 18:00pm");
document.write(myDate);
You need to firstly parse the string to get its components. You can then either generate a Date and use its methods to generate a suitable string, or you can manually reformat the string. Both approaches are very similar.
It's not clear to me why you want the timezone offset. You can get that independently, but if you just transfer all dates as UTC and ISO 8601 then you can just adopt the host timezone offset. If UTC is OK, then you just need to parse to a Date and use toISOString.
It's unusual to specify the time as "18:00pm", the pm part is redundant. Typically it would be specified as "1800hrs", "18:00" or "6:00 pm".
// Reformat string, using Date object for
// host timezone offset only
function reformatDate(s) {
function z(n){return ('0'+n).slice(-2)}
var b = s.match(/\d+|[a-z]+/gi);
var months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
var monNum = months.indexOf(b[1].substr(0,3).toLowerCase());
// Host timezone offset for given date and time
var tzOffset = new Date(b[2], monNum - 1, b[0], b[3], b[4]).getTimezoneOffset();
var tzSign = tzOffset > 0? '-' : '+';
tzOffset = Math.abs(tzOffset);
return b[2] + '-' +
z(monNum) + '-' +
b[0] + 'T' +
b[3] + ':' +
b[4] + tzSign +
z(tzOffset/60 | 0) + ':' +
z(tzOffset%60);
}
// Reformat string using Date object for
// parts and host timezone offset
function reformatDate2(s) {
function z(n){return ('0'+n).slice(-2)}
var b = s.match(/\d+|[a-z]+/gi);
var months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
var monNum = months.indexOf(b[1].substr(0,3).toLowerCase());
var d = new Date(b[2], monNum - 1, b[0], b[3], b[4]);
// Host timezone offset for given date and time
var tzOffset = d.getTimezoneOffset();
var tzSign = tzOffset > 0? '-' : '+';
tzOffset = Math.abs(tzOffset);
return d.getFullYear() + '-' +
z(d.getMonth() + 1) + '-' +
z(d.getDate()) + 'T' +
z(d.getHours()) + ':' +
z(d.getMinutes()) + tzSign +
z(tzOffset/60 | 0) + ':' +
z(tzOffset%60);
}
var s = '02 December 2016 18:00pm';
console.log(reformatDate(s));
console.log(reformatDate2(s));
As you can see, you're really only using a Date to get the timezone offset, the rest of the values can be used as-is except for the month, which must be converted to a number in both cases.
There are also a number of libraries that can help with parsing and formatting strings, such as moment.js (large, widely used, fully functional) and fecha.js (small and functional parser/formatter). In both cases you can parse the string and format it however you wish, e.g. using fecha.js:
var s = '02 December 2016 18:00pm';
// Create a Date
var d = fecha.parse(s, 'DD MMMM YYYY HH:mm');
// Format string
console.log(fecha.format(d, 'YYYY-MM-DDTHH:mmZZ'));
The parse and format can be one statement, but it's clearer as 2. With moment.js (which has better support for chaining methods):
moment(s, 'DD MMMM YYYY HH:mm').format('YYYY-MM-DDTHH:mmZZ');
For the string to be interpretable as a date for conversion, I needed to remove the time "pm" from the back of the string first.
var date = "02 December 2016 18:00pm"
date = date.slice(0, -2);
var myDate = new Date(date);
document.write(myDate);

Date - specific time each day, specific timezone

** UPDATE**
using moment.js would be ok if that would make it easier?
all I'm wanting to do is display a countdown timer that count down to 3pm PST (6EST) daily.
Looking for a way to have javascript get new Date() to use a specific time zome, not the user's time.
I have:
function ShowTime() {
var now = new Date();
var hrs = 14-now.getHours();
var mins = 59-now.getMinutes();
var secs = 59-now.getSeconds();
timeLeft etc etc...
jsfiddle (works) but I think it's my own machine's time:
http://jsfiddle.net/36sqeq8x/
still not working...
I just need to count down to 3pm PST (6EST) daily... without trying to calculate it on users end based on their time zone, like if could calculate from GMT, that would potentially work? but is that even possible.
maybe a combination of something like this?
https://jsfiddle.net/salman/PxzJu/
One way to go about this is to create a Date for the current date and 15:00 in time zone GMT-0800. If that's already passed, add a day to it. If it's more than 1 day in the future (unlikely in a time zone so far west) then subtract a day.
Then subtract the current time from that to get the milliseconds to the next 15:00 PST.
The following makes use of some helper functions, the largest is parseISO to parse an ISO 8601 date string to avoid parsing by the built–in Date parser. toISODate is used to build a string for 15:00 PDT, the others are just for output. Hopefully the documentation and comments is sufficient.
// Create a date for the current date at 15:00 PST (UTC-0800)
// Current date and time
var dLocal = new Date();
// Create Date for same date but time 15:00 at UTC-0800
var dPST = parseISO(toISODate(dLocal) + 'T' + '15:00:00-0800');
// If dPST has passed, add a day
if (dPST < dLocal) dPST.setDate(dPST.getDate() + 1);
// If gap is too big, subtract a day
if (dPST - dLocal > 8.64e7) dPST.setDate(dPST.getDate() - 1);
console.log('Current local: ' + toISOString(dLocal) +
'\nCurrent PST: ' + toISOStringOffset(-480, dLocal) +
'\nNext 3pm PST in PST zone: ' + toISOStringOffset(-480, dPST) +
'\nNext 3pm PST in local zone: ' + toISOString(dPST) +
'\nms to 3pm PST: ' + (dPST - dLocal)
);
/* Parse ISO date string in format yyyy-mm-ddThh:mm:ss.sss+hh:mm or Z
** #param (string} s - string to parse in ISO 8601 extended format
** yyyy-mm-ddThh:mm:ss.sss+/-hh:mm or z
** time zone can omit separator, so +05:30 or +0530
** #returns {Date} - returns a Date object. If any value out of range,
** returns an invalid date.
*/
function parseISO(s) {
// Create base Date object
var date = new Date();
var invalidDate = new Date(NaN);
// Set some defaults
var sign = -1, tzMins = 0;
var tzHr, tzMin;
// Trim leading and trailing whitespace
s = s.replace(/^\s*|\s*$/g,'').toUpperCase();
// Get parts of string and split into numbers
var d = (s.match(/^\d+(-\d+){0,2}/) || [''])[0].split(/\D/);
var t = (s.match(/[\sT]\d+(:\d+){0,2}(\.\d+)?/) || [''])[0].split(/\D/);
var tz = (s.match(/Z|[+\-]\d\d:?\d\d$/) || [''])[0];
// Resolve timezone to minutes, may be Z, +hh:mm or +hhmm
// Splitting into parts makes validation easier
if (tz) {
sign = /^-/.test(tz)? 1 : -1;
tzHr = tz == 'Z'? 0 : tz.substr(1,2);
tzMin = tz == 'Z'? 0 : tz.substr(tz.length - 2, 2)*1;
tzMins = sign * (tzHr*60 + tzMin);
}
// Validation
function isLeap(year){return year % 4 != 0 || year % 100 == 0 && year % 400 != 0}
// Check number of date parts and month is valid
if (d.length > 3 || d[1] < 1 || d[1] > 12) return invalidDate;
// Test day is valid
var monthDays = [,31,28,31,30,31,30,31,31,30,31,30,31];
var monthMax = isLeap(d[0]) && d[1] == 2? 29 : monthDays[d[1]];
if (d[2] < 1 || d[1] > monthMax) return invalidDate;
// Test time parts
if (t.length > 5 || t[1] > 23 || t[2] > 59 || t[3] > 59 || t[4] > 999) return invalidDate;
// Test tz within bounds
if (tzHr > 12 || tzMin > 59) return invalidDate;
// If there's a timezone, use UTC methods, otherwise local
var method = tz? 'UTC' : '';
// Set date values
date['set' + method + 'FullYear'](d[0], (d[1]? d[1]-1 : 0), d[2]||1);
// Set time values - first memeber is '' from separator \s or T
date['set' + method + 'Hours'](t[1] || 0, (+t[2]||0) + tzMins, t[3]||0, t[4]||0);
return date;
}
/* Return ISO 8601 formatted string with local offset, e.g. 2016-06-12T12:43:23.432+05:30
** #param {Date} d - date to craete string from
** #returns {string} in ISO 8601 format with offset
*/
function toISOString(d) {
d = d || new Date();
var offset = d.getTimezoneOffset();
function z(n){return (n<10?'0':'') + n}
// Reverse signe of offset to be consistent with ISO 8601
var offSign = offset < 0? '+' : '-';
offset = Math.abs(offset);
var offHr = z(offset/60 | 0);
var offMin = z(offset%60);
return d.getFullYear() + '-' + z(d.getMonth() + 1) + '-' + z(d.getDate()) + 'T' +
z(d.getHours()) + ':' + z(d.getMinutes()) + ':' + z(d.getSeconds()) + '.' +
('00' + d.getMilliseconds()).slice(-3) + offSign + offHr + ':' + offMin;
}
/* Given a Date, return an ISO 8601 formatted date and time string
** for a particular time zone.
** #param {number} offset - offset in minutes +east, -west, default is local
** #param {Date} d - date to use, default is now
** #returns {string} ISO 8601 formatted string for supplied time zone offset
*/
function toISOStringOffset(offset, d) {
// Copy date if supplied or use now
d = d? new Date(+d) : new Date();
// Prepare offset values
offset = offset || -d.getTimezoneOffset();
var offSign = offset < 0? '-' : '+';
offset = Math.abs(offset);
var offHours = ('0' + (offset/60 | 0)).slice(-2);
var offMins = ('0' + (offset % 60)).slice(-2);
// Apply offset to d
d.setUTCMinutes(d.getUTCMinutes() - offset);
// Return formatted string
return d.getUTCFullYear() +
'-' + ('0' + (d.getUTCMonth()+1)).slice(-2) +
'-' + ('0' + d.getUTCDate()).slice(-2) +
'T' + ('0' + d.getUTCHours()).slice(-2) +
':' + ('0' + d.getUTCMinutes()).slice(-2) +
':' + ('0' + d.getUTCSeconds()).slice(-2) +
'.' + ('000' + d.getUTCMilliseconds()).slice(-3) +
offSign + offHours + ':' + offMins;
}
/* Return an ISO 8601 formatted date string based on local time
** Year must be positive (i.e. doesn't do -ve year)
** #param {Date} date - date object to create date string from
** #returns {string} dates string in yyyy-mm-dd format or default from
** Date.prototype.toString (i.e. "Invalid Date")
*/
function toISODate(date) {
return date.getDate()? ('000' + date.getFullYear()).slice(-4) + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2) : date.toString();
}
The setUTCHours() method sets the hour of a date object, according to the UTC time.
var d = new Date();
d.setUTCHours(15);
Here is the documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours
Alternatively, getUTChours return the hour, according to universal time:
var d = new Date();
var n = d.getUTCHours();
Here is the documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCHours
You can use the getUTCHours() and setUTCHours() functions on a date to get/set the hours based on UTC hours instead of local hours. E.g.
var date = new Date();
date.setUTCHours(5);
Or, better, you can use the getTimezoneOffset() function to show the difference and calculate and adjust back to UTC, or which ever timezone you desire. NB the offset is returned in MINUTES.
var date = new Date();
var offset = date.getTimezoneOffset();
console.log(offset);
My output to the above is 300, as I am in CST (strictly speaking, CDT) which is currently 5 hours behind UTC.

Javascript: how to convert epoch to dd-mm-yyyy

i have an epoch time: x = 1383483902000
I am trying to get a date like: dd-mm-yyyy and want to do this without additional library.
I have tried several ways and my last method end up like :
var date = new Date(Math.round(Number(x)));
but i get an ugly thing like: sun nov 03 2013 14:05:02 GMT+01:00
Use your date object to extract/format the parts you want:
var formattedDate = date.getUTCDate() + '-' + (date.getUTCMonth() + 1)+ '-' + date.getUTCFullYear()
The example below uses the UTC methods of the date object as you are dealing with epoch time (which is milliseconds since epoch in UTC):
var formatDate = function formatDate(date) { // function for reusability
var d = date.getUTCDate().toString(), // getUTCDate() returns 1 - 31
m = (date.getUTCMonth() + 1).toString(), // getUTCMonth() returns 0 - 11
y = date.getUTCFullYear().toString(), // getUTCFullYear() returns a 4-digit year
formatted = '';
if (d.length === 1) { // pad to two digits if needed
d = '0' + d;
}
if (m.length === 1) { // pad to two digits if needed
m = '0' + m;
}
formatted = d + '-' + m + '-' + y; // concatenate for output
return formatted;
},
x = 1383483902000, // sample time in ms since epoch
d = new Date(x), // convert to date object
f = formatDate(d); // pass to formatDate function to get dd-mm-yyyy
console.log(f); // log output to console for testing
You can run this in the browser console as-is.
function formatDate(value: any): any{
let date = new Date(Math.round(Number(value)));
let day = ("0" + date.getDate()).slice(-2);
let month = ("0" + (date.getMonth() + 1)).slice(-2);
let formatDate = date.getFullYear()+"-"+(month)+"-"+(day) ;
return formatDate;
}

Categories

Resources