How can I get the timezone offset from string in javascript? - javascript

I have a string 2021-04-07T13:51:39.664+11:00 which I use to create a Date object: d = new Date('2021-04-07T13:51:39.664+03:00').
After that, d is an instance to represent the date time. Now I'd like to get the timezone offset from d, but d.getTimezoneOffset() always return local timezone offset which is -600 in my case. How can I get the timezone offset from the string? Does it get lost when I build the date instance? Do I have to parse the string to get it?
If I have a date object, how can I generate a string with the offset at the end: 2021-04-07T13:51:39.664+03:00? toISOString() only generate UTC time.
I know moment is a good date library but I don't want to add this dependency since it is too large.

function dateZ(dateString) {
var _date = dateString.substring(0, 23);
var _offset = dateString.substring(23);
var _dateValue = new Date(dateString);
function offset(value) {
if (value) {
_offset = value;
_dateValue = new Date(toString());
}
return _offset;
}
function date(value) {
if (value) {
_date = value;
_dateValue = new Date(toString());
}
return _dateValue;
}
function toString() {
return `${_date}${_offset}`
}
return { offset, date, toString };
}
var d = dateZ('2021-04-07T13:51:39.664+03:00');
console.log(d.date(), d.offset(), d.toString());
d.offset('+05:30');
console.log(d.date(), d.offset(), d.toString());

This is probably not the best possible approach, but it is portable and quite useful if you are in control of the application environment.
friendlyDate = function( x ){
var label = "Day Month Date Year Time Offset".split(" "),
d = x ? new Date(x) : new Date(),
s = ( d + "" ) .split( / / );
s.length = label.length;
for( var x in s )s[ label[ x ] ] = s[ x ];
s.length = 0;
return s
}
/**/
dte = friendlyDate();
for(var x in dte)console.log(x + ": "+ dte[x]);
p.s.: you might need to readjust\rearrange the labels for certain targeted browsers. [Not all browser vendor\version date string representations are returned equal ;)]

How to initialize a JavaScript Date to a particular time zone
There is no time zone or string format stored in the Date object itself.
Seems like either string parsing or a library (there are lighter-weight ones than moment if you're interested).

Related

Comparing Dates in NodeJS IF Statement

I am using nodejs/javascript and trying to compare two dates to each other in order to apply a specific style if the date is before the set date.
Here is what I have:
var d = new Date();
var date = d.getMonth()+1+'/'+d.getDate()+'/'+(d.getFullYear().toString().substr(-2)-1);
var da = new Date('1/4/18');
var da_test = da.getMonth()+1+'/'+da.getDate()+'/'+(da.getFullYear().toString().substr(-2));
if(da_test < date) {
// do something
}
date_test is currently returning the date from a year ago today, 1/23/18. I have set the other date that it will compare itself to, to 1/4/18. While this should be true, for some reason it is not whenever the IF statement runs. However, if I change the date to something like 1/2/18, then it returns true. How is that the case and how can it be changed so it will return true if it is any date before 1/23/18?
You can compare those two dates like this:
const d1 = new Date('1/23/18');
const d2 = new Date('1/4/18');
if (d2 < d1) ...
In your code example you are comparing two Strings
You can compare the milliseconds since epoch (the number of milliseconds since 1 January 1970 00:00:00)
const d1 = new Date('1/23/18');
const d2 = new Date('1/4/18');
if (d2.getTime() < d1.getTime()) {
}
You can also compare ISO date strings
const d1 = new Date('1/23/18');
const d2 = new Date('1/4/18');
if (d2.toISOString() < d1.toISOString()) {
}

Compare a date in string format with todays date

I know this has been asked before but I can't get it to work due to my date format, which I can't change. Any help would be appreciated.
My date is in this format;
4/11/2017 12:30 PM.
If I inspect it in the developer tools it shows it as
4/11/2017 12:30 PM EDIT: Won't show with prepended space here
i.e. with a space in front, not sure if that's relevant.
Does anyone know if it's possible or how to compare it with today's date to see if it's in the past or future?
I've tried tinkering with the following code but can't get it to work because of the time, PM, and forward slashes.
var q = new Date();
var m = q.getMonth();
var d = q.getDate();
var y = q.getFullYear();
var date = new Date(d,m,y);
mydate=new Date('13/04/2017');
console.log(date);
console.log(mydate)
if(date>mydate)
{
alert("greater");
}
else
{
alert("smaller")
}
If you have dates that are in the same format of something like 13/04/2017, you could split the string based on the slashes and compare the values starting from the right moving left.
By this, I mean when you have your array of three values for each date, you could first compare the year, if that's the same, move on to comparing the month, if that's the same then on to comparing the day.
But if for instance one of the year's is 2018 while the other is 2016, you would immediately know that the 2018 one comes later.
var st = "19/05/2019";
var st2 = "19/05/2019";
function provideLaterDate(date1, date2) {
var splitDateDate1 = date1.split("/").reverse();
var splitDateDate2 = date2.split("/").reverse();
var laterDate = false;
splitDateDate1.forEach(function(val, idx, arr) {
if ( laterDate === false ) {
if ( val > splitDateDate2[idx] ) {
laterDate = splitDateDate1;
} else if ( val < splitDateDate2[idx]) {
laterDate = splitDateDate2;
} else {
laterDate = "Both are the same";
}
}
});
if ( /\//.test(laterDate) ) {
return laterDate.reverse().join("/");
} else {
return laterDate;
}
}
To get rid of the "time pm" part, you could simply do something like:
// Assuming your date has a structure like this: 4/11/2017 12:30 PM.
var newDate = unformattedDate.split(" ")[0];
// This will separate your date string by spaces, and since there are no spaces until after the year in your date, the 0 index will give you the date minus the time and pm portion. Please pardon the not-consistent variable names.
The problem was with the way you were constructing date. Construct date like this var mydate = new Date(2017, 04, 03); and it works.
var q = new Date();
var m = q.getMonth();
var d = q.getDate();
var y = q.getFullYear();
var date = new Date(d, m, y);
var mydate = new Date(2017, 04, 03);
console.log(date);
console.log(mydate)
if (date > mydate) {
alert("greater");
}
else {
alert("smaller")
}
You can split the date. Be aware you should contruct your date as follows:
var date = new Date(y,m,d);
Means year first, then month and finally day, as you can see under https://www.w3schools.com/jsref/jsref_obj_date.asp
You can use the following code to perform what you want:
var q = new Date();
var m = q.getMonth();
var d = q.getDate();
var y = q.getFullYear();
var date = new Date(y,m,d);
newdate = '13/04/2017'
array = newdate.split('/');
var d1 = array[0]
var m1 = array[1]-1
var y1 = array[2]
mydate = new Date(y1,m1,d1);
console.log(date);
console.log(mydate)
if(date>mydate)
{
alert("greater");
}
else
{
alert("smaller")
}
You can always check the date created is correct by using the date.toString() function. Be aware 0=January for month as you can check under https://www.w3schools.com/jsref/jsref_getmonth.asp. That's why I added the -1 for var m1.
Problem:
It's not working because you are comparing a date with an Invalid date, it will always return false.
Explanation:
And the Invalid date comes from the line new Date('13/04/2017'), because 13 is expected to be a month number and not a day which is an invalid month, because the new Date(stringDate) will be treated as a local Date and not a UTC date by the browser, and it depends on which browser you are using.
You can see in the JavaScript Date Specification that:
parsing of date strings with the Date constructor (and Date.parse, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. Support for RFC 2822 format strings is by convention only. Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.
Demo:
So if we change new Date('13/04/2017') to new Date('04/13/2017') the code will work as expected:
var date = new Date();
var mydate = new Date('04/13/2017');
console.log(date);
console.log(mydate)
if (date > mydate) {
alert("greater");
} else {
alert("smaller")
}
if(date.getTime()>mydate.getTime()){
alert("greater");
}
else if (date.getTime()==mydate.getTime){
alert("simmilar");
else {alert("smaller");}

JavaScript loop through Json dates

I'm trying to use JavaScript to loop through a json file which has time periods (starting date/time and ending date/time), and check if now (current date time) falls between any time period in such list.
Following is my code, but can't get where I'm wrong. Any help?
<html>
<script type="text/javascript">
var data = {
"period": {
"startend": [{
"startDate": "2015-11-17 15:43:37",
"endDate": "2015-11-18 19:43:37"
}, {
"startDate": "2015-12-17 19:43:37",
"endDate": "2016-01-17 19:43:37"
}, {
"startDate": "2015-04-17 19:43:37",
"endDate": "2015-04-18 19:43:37"
}]
}
}
var periodArray = data.period.startend;
var curDate = new Date();
var datetime = curDate.getFullYear() + '-' + curDate.getMonth() + '-' + curDate.getDate() + ' ' + curDate.getHours() + ':' + curDate.getMinutes() + ':' + curDate.getSeconds();
for (i = 0; i < periodArray.length ; i++) {
var obj = periodArray[i]
if (datetime > obj.startDate && datetime < obj.endDate){
alert('Falls within period');
} else {
alert('Not within any period');
}
}
</script>
The basic idea is to convert the date strings to actual Date objects so they can be compared with the current date (new Date()). Let's begin by defining a helper function that when initialized, closes over the current date, producing a function that takes a start date and an end date, either in String or in Date form, and returns true if and only if the closed over current date is in the range.
Definition.
// () -> (([String|Date] * [String|Date]) -> Boolean)
// When initialized, closes over the current date and returns
// a predicate on String or Date objects.
function includesNow() {
var curDate = new Date();
return function(start, end) {
var startDate = (typeof start === "string")
? new Date(start) : start;
var endDate = (typeof end === "string")
? new Date(end) : end;
return (curDate > startDate) && (curDate < endDate);
};
}
Usage.
With the help of the helper function, we can then pretty easily filter the "current" dates:
// Get the list of (date string) objects.
var allDates = data.period.startend;
// Capture the current date, returning the date range comparator.
var comparator = includesNow();
// Get the list of those (date string) objects `obj`
// that satisfy `comparator(obj.startDate, obj.endDate) === true`.
var currentDates = allDates.filter(function(obj) {
return comparator(obj.startDate, obj.endDate);
});
// This is a function of current date, so will be empty at some point.
currentDates[0];
// => Object {startDate: "2015-11-17 15:43:37", endDate: "2015-11-18 19:43:37"}
If you know your objects will always be Strings and never actual Date objects, then you can simplify includesNow considerably. If you're interested in the closed range be sure to replace > and < with ≥ and ≤, respectively.
JSON date is not a date object. It's a string. You're trying to compare a Date obj to a String.
If the JSON date was an ISO formatted date you could do :
var dateStr = JSON.parse(date);
var realDate = new Date(dateStr);
realDate would now have a js date object. Unfortunately in your example the startDate and endDate are not ISO strings.
This would be the easiest/cleanest solution. Otherwise you could always get the JSON date strings and break them apart with substring() and convert the years/months/days with Number(); and then compare them that way?

How can I check if a Date datatype variable is in the past with Typescript?

I have this function:
isAuthenticationExpired = (expirationDate: Date) => {
var now = new Date();
if (expirationDate - now > 0) {
return false;
} else {
return true;
}
}
Both expirationDate and now are of type Date
Typescript give me an error saying:
Error 3 The left-hand side of an arithmetic operation must be of type
'any', 'number' or an enum type.
Error 4 The right-hand side of an arithmetic operation must be of type
'any', 'number' or an enum type.
How can I check if the date has expired as my way does not seem to work?
Get the integer value representation (in ms since the unix epoch) of the Date now and expirationDate using .valueOf()
var now = new Date().valueOf();
expirationDate = expirationDate.valueOf();
Alternatively, use Date.now()
The standard JS Date object comparison should work - see here
module My
{
export class Ex
{
public static compare(date: Date)
: boolean
{
var now = new Date();
var hasExpired = date < now;
return hasExpired;
}
}
}
var someDates =["2007-01-01", "2020-12-31"];
someDates.forEach( (expDate) =>
{
var expirationDate = new Date(expDate);
var hasExpired = My.Ex.compare(expirationDate);
var elm = document.createElement('div');
elm.innerText = "Expiration date " + expDate + " - has expired: " + hasExpired;
document.body.appendChild(elm);
});
More info:
Compare two dates with JavaScript
JavaScript Date Object

Comparing two dates with javascript or datejs (date difference)

I am trying to compare two dates which are in Finnish time form like this: dd.mm.YYYY or d.m.YYYY or dd.m.YYYY or d.mm.YYYY.
I am having a hard time finding out how to do this, my current code won't work.
<script src="inc/date-fi-FI.js" type="text/javascript"></script>
<script type="text/javascript">
function parseDate() {
var date = $('#date').val();
var parsedDate = Date.parse(date);
alert('Parsed date: '+parsedDate);
}
function jämförMedIdag (datum) {
if (datum == null || datum == "") {
alert('Inget datum!');
return;
}
/*resultat = Date.compare(Datum1,Datum2);
alert(resultat); */
var datum = Date.parse(datum);
var dagar = datum.getDate();
var månader = datum.getMonth();
var år = datum.getYear();
var nyttDatum = new Date();
nyttDatum.setFullYear(år,månader,dagar);
var idag = new Date();
if(nyttDatum>idag) {
var svar = nyttDatum - idag;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
} else {
var svar = idag - nyttDatum;
svar = svar.toString("dd.MM.yyyy");
alert(svar);
return(svar);
}
}
</script>
This code will try to calculate the difference between two dates, one of them being today. No success lolz.
Thanks in advance!
My final code (thanks RobG!):
function dateDiff(a,b,format) {
var milliseconds = toDate(a) - toDate(b);
var days = milliseconds / 86400000;
var hours = milliseconds / 3600000;
var weeks = milliseconds / 604800000;
var months = milliseconds / 2628000000;
var years = milliseconds / 31557600000;
if (format == "h") {
return Math.round(hours);
}
if (format == "d") {
return Math.round(days);
}
if (format == "w") {
return Math.round(weeks);
}
if (format == "m") {
return Math.round(months);
}
if (format == "y") {
return Math.round(years);
}
}
It is not fully accurate, but very close. I ended up adding some addons to it to calculate in day week month year or hour, anyone can freely copy and use this code.
If you are using Datejs, and the optional time.js module, you can run your calculations with the following code by creating a TimeSpan object:
Example
// dd.mm.YYYY or d.m.YYYY
// dd.m.YYYY or d.mm.YYYY
var start = Date.parse("20.09.2011");
var end = Date.parse("28.09.2011");
var span = new TimeSpan(end - start);
span.days; // 8
Of course the above could be simplified down to one line if you really want to be extra terse.
Example
new TimeSpan(Date.parse(end) - Date.parse(start)).days; // pass 'end' and 'start' as strings
Hope this helps.
If your dates are strings in the common form d/m/y or some variation thereof, you can use:
function toDate(s) {
var s = s.split('/');
return new Date(s[2], --s[1], s[0]);
}
You may want to validate the input, or not, depending on how confident you are in the consistency of the supplied data.
Edit to answer comments
To permit different separators (e.g. period (.) or hyphen (-)), the regular expression to split on can be:
var s = s.split(/[/\.-]/);
The date will be split into date, month and year numbers respectively. The parts are passed to the Date constructor to create a local date object for that date. Since javascript months are zero indexed (January is 0, February is 1 and so on) the month number must be reduced by one, hence --s[1].
/Edit
To compare two date objects (i.e get the difference in milliseconds) simply subtract one from the other. If you want the result in days, then divide by the number of milliseconds in a day and round (to allow for any minor differences caused by daylight saving).
So if you want to see how many days are between today and a date, use:
function diffToToday(s) {
var today = new Date();
today.setHours(0,0,0);
return Math.round((toDate(s) - today) / 8.64e7);
}
alert(diffToToday('2/8/2011')); // -1
alert(diffToToday('2/8/2012')); // 365
PS. The "Finnish" data format is the one used by the vast majority of the world that don't use ISO format dates.
Using the Date object:
var today = Date.today();
var dateToday = Date.parse(today.toString('MMMM d, yyyy'));
var prevMonthDate = dateToday.addDays(-30);
var difference = (dateToday - prevMonthDate)/86400000;
console.log(difference); //will give you the difference in days.

Categories