convert a Date string without timezone in nodejs - node.js

I want to convert a string with just the date part, into a Date object in nodejs.
If I do this:
console.log('2010-10-05 ||', new Date('2010-10-05'));
console.log('2010-10-05 00:00:00 ||', new Date('2010-10-05 00:00:00'));
I obtain this in console:
2010-10-05 || Mon Oct 04 2010 19:00:00 GMT-0500 (CDT)
2010-10-05 00:00:00 || Tue Oct 05 2010 00:00:00 GMT-0500 (CDT)
I don't want '2010-10-05' to be converted into '2010-10-04' because of my timezone.
My timezone is -0500 GMT.
How can I create a date by just providing the Date part without the gap ?

Use zeros for hour, minute, second etc.
var date = '2010-10-05',
arr = date.split('-'),
obj = new Date(arr[0], arr[1], arr[2], 0, 0, 0, 0);
Date.UTC uses universal time instead of the local time, if that's what you need
Date.UTC(arr[0], arr[1], arr[2], 0, 0, 0, 0)

console.log('2010-10-05 ||', new Date('2010-10-05' + ' UTC'))
console.log('2010-10-05 00:00:00 ||', new Date('2010-10-05 00:00:00' + ' UTC'))

Related

Read the time frame in the file line by line and assign to a variable in nodejs

I have a file which has values
Start : Wed Dec 18 2019 09:55:15 GMT+0530 (IST)
End : Wed Dec 18 2019 10:11:23 GMT+0530 (IST)
Duration : 00:16:07.278
So I need to get the values coming after
Start :
End :
Duration :
and assign to 3 variables.
Please let me know how we can try that in nodejs
you can parse the date as is with new Date(date string from your file)...
so just split the file into single lines and then remove the starting Start : etc...
as for the Duration, you can split on ":" and then turn the hours and minutes into seconds adding all together in the end...
var st = `Start : Wed Dec 18 2019 09:55:15 GMT+0530 (IST)
End : Wed Dec 18 2019 10:11:23 GMT+0530 (IST)
Duration : 00:16:07.278 `
var lines = st.split("\n")
var start = new Date(lines[0].split("Start :")[1])
var end = new Date(lines[1].split("End :")[1])
var a_dur = lines[2].replace("Duration :", "").split(":")
var dur = Number(a_dur[0]) * 60 * 60 + Number(a_dur[1]) * 60 + Number(a_dur[2])
e_start.innerHTML = start
e_end.innerHTML = end
e_duration.innerHTML = dur
Start:
<div id="e_start"></div><br/> End:
<div id="e_end"></div><br/> Duration:
<div id="e_duration"></div><br/>

Format the time from moment js

When I am trying to receive mail from gmail, I get time in this format (Mon, 12 Jun 2017 10:29:07 +0530). I want to calculate time minus current time. How to do so?
var testDate = moment("Mon, 12 Jun 2017 10:29:07 +0530");
//Relative to time in human readble format
testDate.fromNow(); //3 days ago
You can simply call the moment constructor with the given Date format. moment.js is smart enough to parse it for you. To get the difference you can convert it into unix based time format and subtract it.
const givenTime = moment("Mon, 12 Jun 2017 10:29:07 +0530").unix()
const currentTime = moment().unix()
//Difference in milliseconds
const diff = givenTime - currentTime

momentjs wrong date returned

Im using momentjs in nodejs app and trying to parse timestamp string with momentjs to compare two dates. My code is:
moment('11/04/2016 01:00:00', 'DD/MM/YYYY HH:mm:ss')
and the output is:
{ _date: Fri Nov 04 2016 00:00:00 GMT+0000 (GMT Standard Time) }
But with the given format im expecting the return date to be Sun Apr 10 2016.
Seems like the format option is not working or im missing something
It works for me (moment version: 2.12.0)
var moment = require('moment')
var m = moment('11/04/2016 01:00:00', 'DD/MM/YYYY HH:mm:ss')
console.log(m.format('LLL')) // April 11, 2016 1:00 AM
Also changing days with months in both arguments works:
var m = moment('04/11/2016 01:00:00', 'MM/DD/YYYY HH:mm:ss') // same date as above
What version of moment are you using and how did you import it? How did you generate the output date? Is it just console.log?
(this should be a comment, but I wanted to add the code snippet)
Here's a sample code to return a string in your output format
var moment = require('moment');
var now = moment();
var date = moment('11/04/2016 01:00:00', 'DD/MM/YYYY HH:mm:ss');
console.log(now.format('ddd MMM D YYYY'));
console.log(date.format('ddd MMM D YYYY'));
Sorry it was my mistake. I've installed momentjs which is not the official moment package. After installing the moment package instead momentjs all is working as expected.

TimeCategory add minutes using vars

How do i add minutes to currentDate.
I might add more than 1440 minutes..
def AddMinutes = 1445
currentDate = new Date();
println currentDate
use( TimeCategory ) {
NewCurrentDate = currentDate + AddMinutes.minutes // fails
NewCurrentDate = currentDate + 1445.minutes // works
}
println currentDate
Tue Feb 23 15:09:13 CET 2016
Wed Feb 24 15:14:13 CET 2016
Works for me... Can't see your problem apart from you're not printing out the newCurrentDate (PS: Lower case letters for variable names, otherwise Groovy can get confused, and think you're on about classes -- but that's not the issue here)
import groovy.time.*
def addMinutes = 1445
currentDate = new Date()
use( TimeCategory ) {
newCurrentDate = currentDate + addMinutes.minutes
}
println currentDate //Tue Feb 23 14:45:52 GMT 2016
println newCurrentDate //Wed Feb 24 14:50:52 GMT 2016
I found out that I needed to make sure that the addMinutes was an int. So I added this before in my script:
addMinutes = addMinutes.toInteger()
and now it works.

Ways to deal with Daylight Savings time with Quartz Cron Trigger

I have a quartz cron trigger that looks like so:
<bean id="batchProcessCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="batchProcessJobDetail" />
<property name="cronExpression" value="0 30 2 * * ?" />
</bean>
How should I solve this, if I have several configurations that happen within the 2-3am period? Is there an accepted best practice?
Relevant link: http://www.quartz-scheduler.org/docs/faq.html#FAQ-daylightSavings
Basically it says "Deal with it." But my question is how!
I solved it using a separate trigger that only fires (an hour early) on the beginning date of DST for the configurations that happen between 2am and 3am Eastern.
Seems kludgey, but it works...
We are using the following solution. For this you will also need the joda time library.
public class MyCronExpression extends CronExpression
{
CronExpression _orgCronExpression;
public MyCronExpression(String cronExpression) throws ParseException
{
super(cronExpression);
setTimeZone(TimeZone.getTimeZone("UTC"));
_orgCronExpression = new CronExpression(cronExpression);
}
#Override
public Date getTimeAfter(Date date)
{
Date date1 = super.getTimeAfter(new Date(date.getTime()-date.getTimezoneOffset()*60*1000));
if (TimeZone.getDefault().inDaylightTime( date1 ) && !TimeZone.getDefault().inDaylightTime( date ))
{
DateTimeZone dtz = DateTimeZone.getDefault();
Date dstEnd = new Date(dtz.nextTransition(date.getTime()));
int dstEndHour = dstEnd.getHours();
int dstDuration = (dtz.getOffset(date1.getTime()) - dtz.getStandardOffset(date1.getTime()))/(60*60*1000);
int hour = date1.getHours()+date1.getTimezoneOffset()/60;
if (hour < dstEndHour && hour >= dstEndHour-dstDuration)
return dstEnd;
else
return _orgCronExpression.getTimeAfter(date);
}
else
return _orgCronExpression.getTimeAfter(date);
}
}
The class is used as follows:
CronTriggerImpl trigger = new CronTriggerImpl();
trigger.setCronExpression(new MyCronExpression("0 15 2 * * ?"));
Here some sample trigger times:
Tue Mar 25 02:15:00 CET 2014
Wed Mar 26 02:15:00 CET 2014
Thu Mar 27 02:15:00 CET 2014
Fri Mar 28 02:15:00 CET 2014
Sat Mar 29 02:15:00 CET 2014
**Sun Mar 30 03:00:00 CEST 2014**
Mon Mar 31 02:15:00 CEST 2014
Tue Apr 01 02:15:00 CEST 2014
Wed Apr 02 02:15:00 CEST 2014
Please post if you find any bugs/issues with this solution.
I took Ron's very interesting answer and improved the getTimeAfter Method, In order to adjust it to server GMT running and possible differences when scheduling 'Once a year' cron expressions.
#Override
public Date getTimeAfter(Date date) {
Date nextDate = super.getTimeAfter(date);
if(nextDate == null){
return null;
}
DateTime date1 = new DateTime(nextDate);
if (getTimeZone().inDaylightTime(date1.toDate()) && !getTimeZone().inDaylightTime(date)) {
DateTimeZone dtz = DateTimeZone.forTimeZone(getTimeZone());
DateTime dstEndDateTime = new DateTime(new Date(dtz.nextTransition(date.getTime())));
int dstEndHour = dstEndDateTime.getHourOfDay();
int dstDuration = (dtz.getOffset(date1.getMillis()) - dtz.getStandardOffset(date1.getMillis())) / (60 * 60 * 1000);
int hour = date1.getHourOfDay();
// Verifies if the scheduled hour is within a phantom hour (dissapears upon DST change)
if (hour < dstEndHour && hour >= dstEndHour-dstDuration){
// Verify if the date is a skip, otherwise it is a date in the future (like threads that run once a year)
if(dstEndDateTime.getDayOfYear() == date1.minusDays(1).getDayOfYear()){
return dstEndDateTime.toDate();
}else{
return nextDate;
}
}else{
return nextDate;
}
} else{
return nextDate;
}
}
Please note my server runs in GMT mode, therefore I do not use some of the offset conversions present in Ron's answer.
Also I discovered a Quartz bug, in which if you use the following configuration, it will fail because it is not capable of processing the cron expression correctly:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String cron = "0 15 2 8 3 ? 2015";
FailsafeCronExpression cronExpression = new FailsafeCronExpression(cron);
cronExpression.setTimeZone(DateTimeZone.forID("America/Vancouver"));
DateTime nextDate = new DateTime(cronExpression.getTimeAfter(sdf.parse("12/11/2014 10:15:00")));
This actually seems to happen because DST change takes place during 9th of March 2am for Vancouver and seems the Quartz internal implementation of the super.getTimeAfter(date) method will always send null.
I hope this information is useful.
I'm aware this question is quite old, but it still seems valid. I believe i've found a way to solve this problem, i'l leave it here in case someone else sumbles upon it and finds it handy
With spring 5.3 comes improved scheduling, rewritten using java.time API. It also supports quartz-specific extensions to cron expressions.
Example computation code:
public Instant calculateNextExecution(String cronExpression, Instant lastExecutionInstant, ZoneId executionZoneId) {
LocalDateTime lastExecutionDateTimeInExecutionZone lastExecutionInstant.atZone(executionZoneId)
.toLocalDateTime();
LocalDateTime nextExecutionDateInExecutionZone = CronExpression.parse(cronExpression).next(lastExecutionDateTimeInExecutionZone);
// skipped checking and handling nonexistant next execution
ZoneOffsetTransition transition = executionZoneId.getRules().getTransition(nextExecutionDateInExecutionZone);
if (transition == null) {
// next execution didn't occur during time transition
return nextExecutionDateInExecutionZone.atZone(executionZoneId)
.toInstant();
} else {
// next execution occured during time transition, one might check if transition was a gap or overlap and do sth with it
return doSthWithIt(transition, nextExecutionDateInExecutionZone);
}
}
Relevant spring class is org.springframework.scheduling.support.CronExpression.
Detailed description https://spring.io/blog/2020/11/10/new-in-spring-5-3-improved-cron-expressions
#update: Spring scheduler doesn't support years in cron expressions :( so it might not work in you scenario

Resources