Calculating BST time from Date object? - javascript

I've reviewed a few questions on similar topics already, but none of them address calculating a destination timezone, taking its DST (daylight savings time) into account. I'm trying to write a simple widget that displays a live local time of a specific timezone to anyone visiting the page. The timezone of interest is BST (what is BST?), but if possible I'd love to see a generic implementation for any locale. Here's my attempt, using vanilla JavaScript:
function getBST() {
var date = new Date(),
utc = date.getTime() + date.getTimezoneOffset() * 60000,
local = new Date(utc), // this is GMT, not BST
day = local.getDate(),
mon = local.getMonth() + 1,
year = local.getFullYear(),
hour = local.getHours(),
minute = ('0' + local.getMinutes()).slice(-2),
second = ('0' + local.getSeconds()).slice(-2),
suffix = hour < 12 ? 'AM' : 'PM';
hour = (hour - 24) % 12 + 12;
return mon + '/' + day + '/' + year + ', ' + hour + ':' + minute + ':' + second + ' ' + suffix;
}
setInterval(function () {
document.body.textContent = getBST();
}, 1000);
Based on #RobG's answer, I've written this code:
function resetDay(date) {
date.setUTCMilliseconds(0);
date.setUTCSeconds(0);
date.setUTCMinutes(0);
date.setUTCHours(1);
return date;
}
function lastDay(date, day) {
while (date.getUTCDay() !== day) {
date.setUTCDate(date.getUTCDate() - 1);
}
return date;
}
function adjustDST(date, begin, end) {
if (date >= begin && date < end) {
date.setUTCHours(date.getUTCHours() + 1);
}
return date;
}
function updateBST() {
var date = new Date();
var begin = resetDay(new Date());
begin.setUTCMonth(3, -1);
begin = lastDay(begin, 0);
var end = resetDay(new Date());
end.setUTCMonth(10, -1);
end = lastDay(end, 0);
date = adjustDST(date, begin, end);
var day = date.getUTCDate(),
mon = date.getUTCMonth() + 1,
year = date.getUTCFullYear(),
hour = date.getUTCHours(),
minute = ('0' + date.getUTCMinutes()).slice(-2),
second = ('0' + date.getUTCSeconds()).slice(-2),
suffix = hour < 12 ? 'AM' : 'PM';
hour = (hour - 24) % 12 + 12;
return mon + '/' + day + '/' + year + ', ' + hour + ':' + minute + ':' + second + ' ' + suffix;
}
setInterval(function () {
document.body.textContent = updateBST();
}, 1000);
I tested the BST by pausing in the debugger and changing the month of the current date, and the output was an hour later so it seems to work properly. Thanks for all your help everyone!

It's not possible in pure JS, just using the Date methods, but there's (of course) a lib for that: http://momentjs.com/timezone/
Example:
moment.tz("Europe/London").format(); // 2016-01-15T09:21:08-07:00

It's not difficult to support one timezone provided you know when it transitions in and out of daylight saving.
A javascript Date consists of a time value in UTC and a timezone offset based on the host system settings. So all you need to do is apply the timezone offset that you want to the UTC time and presto, there's your time in any timezone.
There is no standardised system for abbreviating time zones, though there are some defacto standards (e.g. IATA timezone codes and IANA timezones). I guess by BST you mean British Summer Time, also known as British Daylight Time (BDT) and British Daylight Saving Time (BDST). It might also be Bangladesh Standard Time or Bougainville Standard Time which are also known as "BST".
There are various libraries (such as Moment Timezone) that use the IANA codes and can provide the time for any supported time zone for (more or less) any time.
BST starts at 01:00 UTC on the last Sunday in March and ends at 01:00 UTC on the last Sunday in October each year, so the algorithm is:
Create a new date based on the system's local settings (e.g. new Date())
Create dates for the start and end of BST based on UTC values (for this year, 2016-03-27T01:00:00Z and 2016-03-30T02:00:00Z)
See if the current UTC time falls in that range
If so, add 1 hour to the UTC time of the date created in #1
Output a formatted string based on the date's UTC values
That's it, the only hard part is finding the appropriate Sunday dates. You don't need to consider the local timezone offset at all, since everything is based on UTC and Date objects are too.
Right now I don't have time to provide code, so have a go and I can get back to you in about 10 hrs.
Edit
So here's the code. The first two function are helpers, one gets the last Sunday in a month, the other formats an ISO 8601 string with offset. Most of the work is in those two functions. Hopefully the comments are sufficient, if more explanation is required, just ask.
I haven't included milliseconds in the string, feel free to add them if you want, add + '.' + ('00' + d.getUTCMilliseconds()).slice(-3) before the offset part of the formatted string.
Note that the function will need to be modified if the dates for starting or stopping daylight saving are changed, but that is infrequent. Historic dates of course will need a small database of when daylight saving starts and stops for particular years and periods.
/* Return a Date for the last Sunday in a month
** #param {number} year - full year number (e.g. 2015)
** #param {number} month - calendar month number (jan=1)
** #returns {Date} date for last Sunday in given month
*/
function getLastSunday(year, month) {
// Create date for last day in month
var d = new Date(year, month, 0);
// Adjust to previous Sunday
d.setDate(d.getDate() - d.getDay());
return d;
}
/* Format a date string as ISO 8601 with supplied offset
** #param {Date} date - date to format
** #param {number} offset - offset in minutes (+east, -west), will be
** converted to +/-00:00
** #returns {string} formatted date and time
**
** Note that javascript Date offsets are opposite: -east, +west but
** this function doesn't use the Date's offset.
*/
function formatDate(d, offset) {
function z(n){return ('0'+n).slice(-2)}
// Default offset to 0
offset = offset || 0;
// Generate offset string
var offSign = offset < 0? '-' : '+';
offset = Math.abs(offset);
var offString = offSign + ('0'+(offset/60|0)).slice(-2) + ':' + ('0'+(offset%60)).slice(-2);
// Generate date string
return d.getUTCFullYear() + '-' + z(d.getUTCMonth()+1) + '-' + z(d.getUTCDate()) +
'T' + z(d.getUTCHours()) + ':' + z(d.getUTCMinutes()) + ':' + z(d.getUTCSeconds()) +
offString;
}
/* Return Date object for current time in London. Assumes
** daylight saving starts at 01:00 UTC on last Sunday in March
** and ends at 01:00 UTC on the last Sunday in October.
** #param {Date} d - date to test. Default to current
** system date and time
** #param {boolean, optional} obj - if true, return a Date object. Otherwise, return
** an ISO 8601 formatted string
*/
function getLondonTime(d, obj) {
// Use provided date or default to current date and time
d = d || new Date();
// Get start and end dates for daylight saving for supplied date's year
// Set UTC date values and time to 01:00
var dstS = getLastSunday(d.getFullYear(), 3);
var dstE = getLastSunday(d.getFullYear(), 10);
dstS = new Date(Date.UTC(dstS.getFullYear(), dstS.getMonth(), dstS.getDate(),1));
dstE = new Date(Date.UTC(dstE.getFullYear(), dstE.getMonth(), dstE.getDate(),1));
// If date is between dstStart and dstEnd, add 1 hour to UTC time
// and format using +60 offset
if (d > dstS && d < dstE) {
d.setUTCHours(d.getUTCHours() +1);
return formatDate(d, 60);
}
// Otherwise, don't adjust and format with 00 offset
return obj? d : formatDate(d);
}
document.write('Current London time: ' + getLondonTime(new Date()));

London Time / BST:
const now = new Date();
console.log(now.toLocaleString('en-GB', { timeZone: 'Europe/London' }));

Related

How to get a ISO 8601 string like how Moment formats it with the native API? [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.

JavaScript print date as UTC and ISO [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.

Parse date in javascript using CET as default timezone

I have some legacy webservices that sometimes does not localize dates. Sometimes they do, so I have to support both cases.
They shall always use Italy's locale (UTC+1 for standard time, and UTC+2 for daylight saving time), but sometimes they return dates omitting the timezone at the end of date ISO strings.
For example, the italian new year should be 2018-01-01T00:00:00+0100 and they instead return only 2018-01-01T00:00:00
This causes bad behaviour in Javascript, especially when dealing with deadlines and clients that are in other timezones.
I'd like to be able to write a piece of code that parses a date string in ISO format, assuming italian localization if there is no timezone specified.
My code is almost ok (it doesn't parse milliseconds, but I can live with that), unfortunately it miserably fails when executed by browsers in timezones that doesn't have daylight saving time. What should I do? Am I missing something?
Thanks in advance
/**
* Get the local timezone using standard time (no daylight saving time).
*/
Date.prototype.stdTimezoneOffset = function() {
var jan = new Date(this.getFullYear(), 0, 1);
var jul = new Date(this.getFullYear(), 6, 1);
return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}
/**
* Check whether current time is daylight saving time.
*/
Date.prototype.isDst = function() {
return this.getTimezoneOffset() < this.stdTimezoneOffset();
}
/**
* Check whether daylight saving time is observed in current timezone.
*/
Date.prototype.isDstObserved = function() {
var jan = new Date(this.getFullYear(), 0, 1);
var jul = new Date(this.getFullYear(), 6, 1);
return jan.getTimezoneOffset() != jul.getTimezoneOffset();
}
/**
* Cross-browser parse of a date using CET as default timezone.
*/
Date.parseFromCET = function(str) {
if (str == null) return null;
// split the input string into an array of integers
var a = str.split(/[^0-9]/)
.map(function(s) {
return parseInt(s, 10)
});
var b = new Date(
a[0], // yyyy
a[1] - 1 || 0, // MM
a[2] || 1, // dd
a[3] || 0, // hh
a[4] || 0, // mm
a[5] || 0 // ss
);
// if no timezone is present, force to CET
if (str.lastIndexOf('-') <= 7 && str.indexOf('+') == -1 && str.indexOf('Z') == -1) {
var CET_timezone_offset = b.isDst() ? '+0200' : '+0100'
var isoString = a[0] + '-' + a[1] + '-' + a[2] + 'T' +
a[3] + ':' + a[4] + ':' + a[5] + CET_timezone_offset;
return Date.parseFromCET(isoString);
}
// remove local timezone offset to go from UTC time to local time
b.setMinutes(b.getMinutes() - b.getTimezoneOffset());
// add/remove forced timezone offset to calculate exact local time
if (str.indexOf('+') > -1) {
let hours = Math.floor(a[a.length - 1] / 100);
let minutes = a[a.length - 1] % 100;
b.setMinutes(b.getMinutes() - minutes);
b.setHours(b.getHours() - hours);
}
if (str.lastIndexOf('-') > 7) {
let hours = Math.floor(a[a.length - 1] / 100);
let minutes = a[a.length - 1] % 100;
b.setMinutes(b.getMinutes() + minutes);
b.setHours(b.getHours() + hours);
}
return b;
}
The timestamp isn't consistent with the format in ECMA-262 as it's missing a colon in the offset. So parsing is implementation dependent and you may get an invalid date (e.g. in Safari).
The standard offset for Rome is +01:00. Daylight saving starts at 02:00 on the last Sunday in March (change to +02:00), and ends at 02:00 on the last Sunday in October (back to +01:00).
Note that there have been historical changes. Italy started using daylight saving in 1916, but there have been periods where it wasn't observed. It has been observed continuously since 1965, so as long as your dates are after that, you don't have to worry about past changes, only future ones.
The following is one way to go about it, it needs a lot more testing and should do validation of the input string and resulting Date object. You should probably also handle a timezone of "Z".
If you're going to do this a lot, a library that manages timezones will help greatly as it should also handle historical changes, past and future.
/** Get a Date for the last Sunday of the month
* #param {number|string} year - year for month
* #param {number|string} month - calendar month number, 1 = Jan, 2 = Feb, etc.
* #returns {Date} date for last Sunday for given year and month
*/
function getLastSunday(year, month) {
// Date for last day of month
var d = new Date(Date.UTC(year, month, 0));
// Adjust to previous Sunday
d.setUTCDate(d.getUTCDate() - d.getUTCDay());
return d;
}
/** Return a date set to the UTC start of Italian DST
* Starts at +0300 UTC on the last Sunday in March
*
* #param {number|string} year to get start of DST for
* #returns {Date} set to start date and +0300Z
*/
function getDSTStart(year) {
var d = getLastSunday(year, 3);
d.setUTCHours(3);
return d;
}
/** Return a date set to the UTC end of Italian DST
* Ends at +0400 UTC on the last Sunday in October
*
* #param {number|string} year to get start of DST for
* #returns {Date} set to start date and +0400Z
*/
function getDSTEnd(year) {
var d = getLastSunday(year, 10);
d.setUTCHours(4);
return d;
}
/** Given a year, month, day and hour, return
* true or false depending on whether DST is
* being observed in Italy.
* Use UTC to avoid local influences, assume standard time
*
* #param {number|string} year - subject year
* #param {number|string} month - subject calendar month
* #param {number|string} day - subject day
* #param {number|string} hour - subject hour
* #returns {number} offset for provided date and time
*/
function getItalianOffset(year, month, day, hour) {
var d = new Date(Date.UTC(year, month-1, day, +hour + 1));
return d >= getDSTStart(year) && d < getDSTEnd(year)? '+0200' : '+0100';
}
/** Convert offset in format +0000 to minutes
* EMCAScript offset has opposite sign
*
* #param {string} offset - in format +/-HHmm
* #reaturns {number} offset in minutes, + for west, - for east
*/
function offsetToMins(offset) {
sign = /^\+/.test(offset)? -1 : 1;
tz = 60 * offset.slice(-4, -2) + (1 * offset.slice(-2));
tz *= sign;
return tz;
}
/** Parse timestamp that may or may not have a timezone.
* If no timezone, assume Italian timezone (+0100), adjusting for
* daylight saving.
* DST starts at +0300Z on last Sunday in March
* DST ends at +0400Z on last Sunday in October
* 2018-01-01T00:00:00+0100 or 2018-01-01T00:00:00
*/
function parseItalianDate(s) {
var b = s.split(/\D/);
var hasTz = /[+-]\d{4}$/.test(s);
var d, sign, tz;
// If has offset, get from string
// Otherwise, calculate offset
if (hasTz) {
tz = s.slice(-5);
} else {
tz = getItalianOffset(b[0], b[1], b[2], b[3]);
}
// Create Date using correct offset
d = new Date(Date.UTC(b[0], b[1]-1, b[2], b[3], b[4], b[5]));
d.setUTCMinutes(d.getUTCMinutes() + offsetToMins(tz));
return d;
}
// Tests
['2018-01-01T00:00:00', // New year
'2018-03-25T01:00:00', // One hour before change over
'2018-03-25T03:00:00', // One hour after change over
'2018-03-25T01:00:00+0100',// As above but with timzone offset
'2018-03-25T03:00:00+0200',
'2018-10-27T03:00:00', // Still in DST
'2018-10-28T03:00:00', // After DST ended
'2018-10-28T03:00:00+0100'
].forEach(function(s) {
console.log(`${s} => ${formatDate(parseItalianDate(s))}`);
});
// Helper to format a date in Europe/Rome timezone
function formatDate(d) {
return d.toLocaleString('en-GB',{
year : 'numeric',
month : 'short',
day : '2-digit',
weekday: 'short',
hour : '2-digit',
minute : '2-digit',
second : '2-digit',
hour12 : 'false',
timeZone: 'Europe/Rome',
timeZoneName: 'short'
});
}
As RobG mentioned in his great answer, you'll have an easier time if you use a library for this. There are several to choose from. A good choice for modern applications is Luxon, which will support all of the scenarios you described. Here are some examples:
let dt = DateTime.fromISO('2018-01-01T00:00:00+0100', { setZone: true, zone: 'Europe/Rome'});
console.log(dt.toISO()); //=> "2018-01-01T00:00:00.000+01:00"
let dt = DateTime.fromISO('2018-01-01T00:00:00', { setZone: true, zone: 'Europe/Rome'});
console.log(dt.toISO()); //=> "2018-01-01T00:00:00.000+01:00"
let dt = DateTime.fromISO('2018-07-01T00:00:00', { setZone: true, zone: 'Europe/Rome'});
console.log(dt.toISO()); //=> "2018-07-01T00:00:00.000+02:00"
A few notes about the above:
fromISO will accept the offset missing, or with Z, or with an offset with or without a colon.
setZone: true tells it to keep the offset from the string if one is provided.
zone: 'Europe/Rome' tells it to use the time zone for Italy when no offset is provided.
You can, of course, use the Luxon DateTime object (dt here) in a variety of ways other than just emitting a string with toISO().
There are other libraries that can do such things, such as moment-timezone, and js-joda, but I prefer Luxon lately.

Number of milliseconds in IST date format in JS

I am giving input date and time in IST, but it gives me milliseconds in UTC. How can I get milliseconds in IST.
var atPos = "03:00";
var jsonDate = new Date("2016"+ "-0" + "7" + "-" + "14" + "T" + atPos);
console.log(jsonDate.getTime()); // getting in UTC
It's not clear to me what you are expecting. A function to parse an ISO 8601 date and time with an offset is not difficult (less than 20 lines, there are examples on SO). Nor is it difficult to output date and time values for a specific time zone, regardless of host settings.
If you wish to trust the built–in Date parser (which is not recommended) then you can create an ISO 8601 compliant string that contains an offset of +05:30 (for India Standard Time) and parse that, e.g.
var atPos = "03:00";
var jsonDate = new Date("2016+ "-0" + "7" + "-" + "14" + "T" + atPos + "+05:30");
Date time values are UTC per ECMA-262, you can't change that, so when you do:
console.log(jsonDate.getTime()); // getting in UTC
you will always get a UTC time value. However, if you use that value to create a Date (as in new Date(timevalue)), then the result will represent the same instant in time regardless of host settings.
Following is a function to output a date string with any specified offset. If the comments aren't sufficient, just ask. ;-)
/* Return an ISO 8601 long format string with the specified offset
**
** #param {Date} date - date to format
** #param {string} offset - offset as "+hh:mm" or "+hhmm" or "Z"
** default is host time zone
** if sign is missing, default is "+"
** #returns {string} ISO 8601 extended format
*/
function formatISO(date, offset) {
function z(n) {return ('0' + n).slice(-2)}
function zz(n){return ('00' + n).slice(-3)}
if (!date) return;
// Copy date
var d = new Date(+date);
// Convert offset to minutes
var offSign = '+';
if (typeof offset == 'undefined') {
offset = date.getTimezoneOffset();
offSign = offset < 0? '+' : '-';
offset *= -1;
} else if (/z/i.test(offset)) {
offset = 0;
} else {
offSign = /^-/.test(offset)? '-' : '+';
var t = offset.match(/\d\d/g);
offset = (t[0]*60 + t[1]*1) * (offSign == '-'? -1 : 1);
}
// Adjust d to desired offset
d.setUTCMinutes(d.getUTCMinutes() + offset);
// Create timezone string
offset = Math.abs(offset);
offset = offset? offSign + z(offset/60 | 0) + ':' + z(offset % 60) : 'Z';
// Create string
return d.getUTCFullYear() + '-' +
z(d.getUTCMonth() + 1) + '-' +
z(d.getUTCDate()) + 'T' +
z(d.getUTCHours()) + ':' +
z(d.getUTCMinutes()) + ':' +
z(d.getUTCSeconds()) + '.'+
zz(d.getUTCMilliseconds()) +
offset;
}
console.log(formatISO(new Date())) // Host
console.log(formatISO(new Date(),'+05:30')) // IST
console.log(formatISO(new Date(),'-0800')) // US AKDT
console.log(formatISO(new Date(),'z')) // UTC
sss Milliseconds 00 to 999
document.writeln((new Date("2010")).toUTCString());
document.writeln((new Date("2010-06")).toUTCString());
document.writeln((new Date("2010-06-09")).toUTCString());
// Specifies Z, which indicates UTC time.
document.writeln((new Date("2010-06-09T15:20:00Z")).toUTCString());
// Specifies -07:00 offset, which is equivalent to Pacific Daylight time.
document.writeln((new Date("2010-06-09T15:20:00-07:00")).toGMTString());
// Specifies a non-ISO Long date.
document.writeln((new Date("June 9, 2010")).toUTCString());
// Specifies a non-ISO Long date.
document.writeln((new Date("2010 June 9")).toUTCString());
// Specifies a non-ISO Short date and time.
document.writeln((new Date("6/9/2010 3:20 pm")).toUTCString());
store that millisecond into a variable and then use new date function your job would be done
check out this to convert into millisecond
<!DOCTYPE html>
<html>
<body>
<p>Click the button to display the numbers of milliseconds between a specified date and midnight January 1, 1970.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var d = Date.UTC(2012, 02, 30);
document.getElementById("demo").innerHTML = d;
var milliseconds= document.getElementById(demo);
var d = new Date(milliseconds);
alert(d.toUTCString());
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = new Date("2015-03");
</script>
</body>
</html>

javascript Date or next date based on time of day and if/else

I want to show the my current shipping time on my website. Each day I have a 2:00 pm cut of and would like the date to change to the following week day. Right now I have to manually change it every day
Currently Shipping:
Tuesday, April, 24th
Cut-off Time:
2:00 pm PST
I have done enough research to believe this is possible but I do not know enough about manipulating the script myself to take the pieces and put it all together.
The two o'clock doesn't usually change so I hope I can use a script to automatically change (just the Day, Month and Date) at the specified time
Please advise Thanks!
What I have tried to put together so far
var currentTime = new Date();
var month = currentTime.getDay();
var month = currentTime.getMonth() + 1;
var date = currentTime.getDate();
var thehour = datetoday.getHours();
if(thehour < 14) { document.write(day + "," + month + "," + date) }
else if (thehour > 14) ...
Firstly, you must do this on the server since the client machine doesn't know the right time zone offset (it might be -8 hours or -7 hours depending on whether it's daylight saving time or not) and the client clock may not be accurately set (or might be deliberately incorrectly set).
So if you are going to send the offset to the client, you might as well just send the time. And when you send the zone, don't just send PST since that is ambiguous to many, send the actual offset (UTC -8 or -7 as appropriate). Or send the cutoff time in UTC and let the user work it out.
As an example, to convert the local time to some other time zone, you can do:
var pstOffset = 480; // Standard time offset
var pdtOffset = 420 // Daylight saving offset
var now = new Date();
// Adjust to PST
now.setMinutes(now.getMinutes() + now.getTimezoneOffset() - pstOffset);
alert(now); // Time in PST
But note that the date object is still in the local time zone because you can't change the actual offset, only adjust the time to allow for it.
To send the cut-off time and convert it to a local time, the easiest way is to send a UTC timestamp and convert it on the local box, so:
var ts = '2012-04-24T08:00:00Z'; // UTC cut-off for standard time on 24/4
var tsd = '2012-04-24T07:00:00Z'; // UTC cut-off for daylight saving time on 24/4
function utcToLocal(s) {
var bits = s.split(/[-T:Z]/g); // Split string into useful bits
var d = new Date();
// Set local date object to UTC supplied time
d.setUTCFullYear(bits[0], bits[1] - 1, bits[2]);
d.setUTCHours(+bits[3], +bits[4], +bits[5]);
return d;
}
alert( 'Your clock says it\'s now ' + (new Date()) +
'\nThe cut-off for shipping is ' + utcToLocal(ts));
And send the appropriate UTC timestamp based on the server time (e.g. if they've missed the shipping time for 24 April, send them the one for 25 April).
Edit
Here's a full solution, but remember I've said don't do this on the client:
/* Get the cut-off of 2pm PST or PDT on current or
* next working day. If d is true (e.g. 1) use PDT,
* otherwise use PST
**/
function setCutoffTime(d) {
var pstOffset = 480; // PST offset in minutes
var psdOffset = 420; // PDT offset in minutes
var now = new Date();
var addDays = 0;
var cutoff;
var days = 'Sun Mon Tue Wed Thu Fri Sat Sun'.split(' ');
var months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
// Utility to add a leading zero
function addZ(n) {
return (n<10?'0':'') + n;
}
// Convert to PST time
now.setMinutes(now.getMinutes() +
now.getTimezoneOffset() - (d? psdOffset : pstOffset));
// If after 2pm, push to tomorrow
if (now.getHours() > 14) now.setHours(now.getHours() + 12);
// If on a weekend, push to Monday
if (now.getDay() == 6) addDays = 2;
if (now.getDay() == 0) addDays = 1;
now.setDate(now.getDate() + addDays);
// Now on working day pre 2pm, so set time to 14:00
now.setHours(14, 0, 0);
// And convert back to local time
now.setMinutes(now.getMinutes() - now.getTimezoneOffset() +
(d? psdOffset : pstOffset));
// Return a formatted string - should be a separate function
return 'Shipping cut-off: ' +
addZ(now.getHours()) + ':' +
addZ(now.getMinutes()) + ' on ' +
days[now.getDay()] + ', ' +
now.getDate() + ' ' +
months[now.getMonth()] +
', ' + now.getFullYear();
}
alert(setCutoffTime()); // Cut-off for PST
alert(setCutoffTime(true)); // Cut-off for PDT

Categories