Compare two dates in cypress - javascript

How can I compare two dates in Cypress without them beeing modified?
let today = new Date();
let dateDisplayed = "22.07.2022".split('.');
let dateToCompare = new Date(
+dateDisplayed[2],
+dateDisplayed[1] - 1,
+dateDisplayed[0]
);
let firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
expect(dateToCompare).greaterThan(firstDayOfMonth);
When I run the tests I get the following output.
Does the 'expect' function modify my date values? It seems that both values are decreased by one day. How do I overcome this problem?
Thanks for your help!

They aren't modified as much as translated from your time zone (Central European Summer Time, is it?) to GMT. Your midnight is 10pm in Greenwich.
Considering that it happened to both dates, it doesn't change the result of the comparison.
If it nevertheless bothers you, there's Cypress' clock function to influence how it handles, among other things, Date objects.
https://docs.cypress.io/api/commands/clock

You can use day.js library for this. For assertion, you can apply the isAfter to compare both the dates like below:
const dayjs = require('dayjs')
describe('test suite', () => {
it('Test', () => {
let dateDisplayed = '22.07.2022'.split('.')
let dateToCompare =
dateDisplayed[2] +
'-' +
(+dateDisplayed[1] - 1).toString() +
'-' +
dateDisplayed[0]
let firstDayOfMonth = dayjs().startOf('month') //2022-07-01T00:00:00+03:00
const result = firstDayOfMonth.isAfter(dayjs(dateToCompare))
cy.then(() => {
expect(result).to.eq(true)
})
})
})

Related

Moment js. Comparison two dates

How to compare two dates with moment js. I used diff() method , but not worked. How I solve it ?
let lastMessageMinute = moment("06-30-2022").format("HH:mm");
let currentTime = moment(new Date()).format("HH:mm");
const differenceOfTimes = currentTime.diff(lastMessageMinute, "hours");
Convert both dates (before formatting) to milliseconds and compare them. Like
if(lastMessageMinute.valueOf() === currentTime.valueOf())
you need to do like moment().diff()
Your syntax -> moment().format().diff() this is not accept by moment js.
For Example,
var a = moment("18.05.2022", "DD.MM.YYYY");
var b = moment(new Date(), "DD.MM.YYYY");
console.log("diff", b.diff(a, 'hours'));

Check if given date is in last 3 weeks

I have a sample date:
const date = '10-03-2022';
I need to check if this date is longer than 3 weeks or not. Or speaking differently - I need to check if this date is in the last 3 weeks or older.
I was trying with date-fns but its not the result I expect.
import { formatDistance, subWeeks } from 'date-fns'
formatDistance(subWeeks(new Date(), 3), date)
I dont have to be honest any idea how to deal with such problem. Thats why I wanted to ask you here for help. Thanks!
You can use isAfter to compare against subWeeks. This will return true even if the date is in the future from now.
Alternatively you can use isWithinInterval to test if the date is within the period between now and three weeks before now. (not included in the cdn version available).
const dateIsWithinInterval = isWithinInterval(testDate,
{ start: subWeeks(new Date(), 3), end: new Date() })
You'll still need to parse your string into a valid Date object.
//import { isAfter, subWeeks } from 'date-fns';
const { isAfter, subWeeks } = dateFns; // cdn assignment
const dateString = '10-06-2022';
const [d, m, y] = dateString.split('-').map(n => parseInt(n, 10));
// months are 0 indexed so you need to subrtract 1.
const testDate = new Date(y, m - 1, d);
const dateIsAfter = isAfter(testDate, subWeeks(new Date(), 3));
console.log('isAfter:', dateIsAfter);
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/2.0.0-alpha0/date_fns.min.js" integrity="sha512-0kon+2zxkK5yhflwFqaTaIhLVDKGVH0YH/jm8P8Bab/4EOgC/n7gWyy7WE4EXrfPOVDeNdaebiAng0nsfeFd9A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Javascript find time difference in hours with timezone

I have a javascript object with the following details:
var dateobj = {
date: "2020-12-21 03:31:06.000000",
timezone: "Africa/Abidjan",
timezone_type: 3
}
var date = new Date();
var options = {
timeZone: dateobj.timezone
};
var curr_date = date.toLocaleString('en-US', options)
console.log(curr_date)
//I want this
//diff = curr_date - dateobj.date
I want to find the time difference in hours with the current date-time of the same timezone. I know I can use toLocaleString() function to get the date-time string in a particular timezone, but how can I find the time difference? The above code gets the current date time in that timezone, how can I find the time difference in hours?
In general when working with dates in JS I usually use a library called date-fns (Date functions). It just makes dates and time a lot easier to manage. This is how you would get the time difference in hours with date-fns.
const { differenceInHours } = require("date-fns");
const { zonedTimeToUtc } = require("date-fns-tz");
const timeData1 = {date: "2020-12-21 03:31:06.000000", timezone: "Africa/Abidjan", timezone_type: 3};
const timeData2 = {date: "2020-12-21 03:31:06.000000", timezone: "America/Los_Angeles", timezone_type: 3};
const t1 = zonedTimeToUtc(timeData1.date, timeData1.timezone);
const t2 = zonedTimeToUtc(timeData2.date, timeData2.timezone);
const diff = differenceInHours(t2, t1);
console.log(diff);
// => 8
Run demo: https://runkit.com/embed/jtfu0ixxthy7

How to use startOfDay from date-fns with timezones?

I try to replace momentjs with date-fns
but I am struggling with a very simple thing:
I need to calculate startOfDay, end of day and addDays for the dates that I have got in timestamps and according to the giving timezone.
date = 1492437600; // Monday April 17, 2017 12:00:00 (pm) in time zone America/Noronha
timeZone = 'America/Noronha';
_startOfDay = utcToZonedTime(startOfDay(date*1000), timeZone).getTime()/1000;
and I have got the result for the _startOfDay = 1492365600 that is Sunday April 16, 2017 16:00:00 (pm) in time zone America/Noronha
What I am doing wrong?
thanks in advance
Note: See the bottom of this answer for the best solution
Old Answer:
I see this question is 11 months old (as of writing) but thought I'd answer it as I hit the same problem, and others may come here in the future with the same question.
The date-fns library doesn't have timezone support, so you need to also use the date-fns-tz library. Import the getTimezoneOffset function from date-fns-tz and use to calculate the offset between the local (browser) timezone and the timezone you wish to calculate end of day for (i.e. America/Noronha). Note that the date-fns "endOf" functions use the local/browser timezone.
E.g.
import { endOfDay } from 'date-fns';
import { getTimezoneOffset } from 'date-fns-tz/esm';
const MILLISECS_IN_DAY = 86400000;
const localTz = Intl.DateTimeFormat().resolvedOptions().timeZone; // Browser Timezone
const tzOffset = getTimezoneOffset('America/Noronha') - getTimezoneOffset(localTz);
// Have to cater for negative offsets
const tzOffsetEOD = (tzOffset < 0) ? (MILLISECS_IN_DAY + tzOffset) : tzOffset;
let testDate = new Date();
let eodInTimezone = endOfDay(testDate).getTime() - tzOffsetEOD; // in millisecs
// Have to project forward a day if the result is in the past
if (eodInTimezone < testDate.getTime()) eodInTimezone += MILLISECS_IN_DAY;
Someone may be able to come up with a more elegant solution to this problem. If I do I'll post back here.
New Answer:
This solution works best for all "End Of" date-fns functions:
import { endOfDay, endOfWeek, endOfMonth, endOfYear } from 'date-fns';
import { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz/esm';
const calcZonedDate = (date, tz, fn, options = null) => {
const inputZoned = utcToZonedTime(date, tz);
const fnZoned = (options) ? fn(inputZoned, options) : fn(inputZoned);
return zonedTimeToUtc(fnZoned, tz);
}
const getZonedEndOfDay = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfDay);
}
const getZonedEndOfWeek = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfWeek, { weekStartsOn: 1 });
}
const getZonedEndOfMonth = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfMonth);
}
const getZonedEndOfYear = (date, timeZone) => {
return calcZonedDate(date, timeZone, endOfYear);
}
// Example Usage
let endOfDayZoned = getZonedEndOfDay(new Date(), 'America/Noronha');
Hope this helps.

Javascript functional programming and dynamic values in an Array

I am trying to write a function that grabs the first 14 days (starting today) with momentJS. My function currently looks like
let dateArr = Array(14).fill(moment())
.map((date) => {
return date.add(1, 'days')
});
I understand that fill is for static values and not dynamic ones, so how would I go about fixing this up so that I have an array that has, ['11/12', '11/13', '11/14', etc...]
I think i need some sort of recursion so that it adds 1 day from the last iteratee, or else i think it'll just keep adding 1 day from today for each iteration
Array(14).fill(moment())
.map((date, i) => date.add(1, 'days').format('MM/DD'));
OUTPUT:
(14) ["01/13", "01/14", "01/15", "01/16", "01/17", "01/18", "01/19", "01/20", "01/21", "01/22", "01/23", "01/24", "01/25", "01/26"]
UPDATE:
Start from today^
Array(14).fill(moment())
.map((date, i) => {
if(i === 0) {
return date.format('MM/DD')
}
return date.add(1, 'days').format('MM/DD')
});
(14) ["01/12", "01/13", "01/14", "01/15", "01/16", "01/17", "01/18", "01/19", "01/20", "01/21", "01/22", "01/23", "01/24", "01/25"]
What you are doing is filling an array with a SINGLE date object, like doing this:
let date = moment();
let dateArr = Array(14).fill(date)
.map((date, index) => {
return date.add(index, 'days')
});
moment.add() will not return a new date object, but modify the current date object. What you need is to retrieve a new date object on each map (instead of returning the same date object):
let dateArr = Array(14).fill(moment())
.map((date, index) => {
return date.clone().add(index, 'days'); // Note the `clone()` so a new object is created.
});
And if you want to just retrieve a string, just add a format:
let dateArr = Array(14).fill(moment())
.map((date, index) => {
return date.clone().add(index, 'days'.format('MM/DD'); // Note the `clone()` so a new object is created.
});
Also note how a index is used to add days dinamically depending on the array position, hence first position will be today (adding 0 days).
I hope I understand you right. You will get all days from maybe today +14 days in the future. But I dont understand why you will use fill() methode?
Then that will work for you:
var getDaysArray = function(year, month, day) {
var date = new Date(year, month, day);
var result = [];
var i;
for (i=0;i<14;i++) {
result.push(date.getMonth() + '/' + date.getDate());
date.setDate(date.getDate() + 1);
}
return result;
}
console.log(getDaysArray(2021,1,12) )

Categories

Resources