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>
Related
Library moments.js included.
I have a variable "lastMessage.created_at"
If it today's date to display then time in the format "h:mm a" if it was yesterday, display "Yesterday" or before that "D.M.Y", how do I do this ?
You could create a function to format input dates, these can be strings (in supported formats), Dates or moment objects.
We'll then output a different format based on whether the date is the same or after the start of today, the start of yesterday, or before that.
function formatDisplayDate(input) {
const dt = moment(input);
const startOfToday = moment().startOf('day');
const startOfYesterday = moment().startOf('day').subtract(1, 'day');
if (dt.isSameOrAfter(startOfToday)) {
return dt.format('h:mm a');
} else if (dt.isSameOrAfter(startOfYesterday)) {
return 'Yesterday';
} else {
// Before yesterday
return dt.format('D.M.Y');
}
}
const inputs = [ new Date().toLocaleString('sv'), new Date(Date.now() - 86400000).toLocaleString('sv'), new Date(Date.now() - 4*86400000).toLocaleString('sv') ];
for (let input of inputs) {
console.log(`Input: ${input}, output: ${formatDisplayDate(input)}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" referrerpolicy="no-referrer"></script>
I need to convert this from moment.js moment(date, 'DD MM YYYY').isBefore(moment()) to date-fns.
I tried isBefore(format(value, 'dd-MM-yyyy'), sub(new Date(), { days: 1 })). I mention that now I have to substract 1 day.
So the functionality will be to compare value which is the date given with currentDate - 1 day.
Essentially, check if future date is given, (future date includes current day).
Hope this is clear enough. My example doesn't work and I don't understand why.
Looks like you're using format instead of parse. isBefore accepts a number or Date not a string as its first argument.
See example:
function compareDate(value: string) {
return isBefore(
parse(value, 'dd-MM-yyyy', new Date()),
sub(new Date(), { days: 1 })
);
}
const test = compareDate('31-12-2020');
console.log(test);
As requested in comments
We can run the value against a function that replaces all / and \s to -.
function unifyDateString(value: string) {
try {
return value.split("/").join("-").split(" ").join("-");
} catch {
return value;
}
}
function compareDate(value: string) {
return isBefore(
parse(unifyDateString(value), "dd-MM-yyyy", new Date()),
sub(new Date(), { days: 1 })
);
}
const one = compareDate("31-12-2020");
const two = compareDate("31/12/2020");
const three = compareDate("31 12 2020");
console.log(one);
console.log(two);
console.log(three);
This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 2 years ago.
Tried this:
1.
const today = new Date('28.08.2020');
const milliseconds = today.getTime();
const today = Date.parse("28.08.2020")
var today = new Date('28.08.2020');
var milliseconds = today.getMilliseconds();
Getting NaN while trying to convert a string of date to milliseconds
Better to change date format to YYYY-MM-DD as suggested in other answer
Or you can do something like this
var from = '28.08.2020'.split(".");
var today = new Date(from[2], from[1] - 1, from[0]);
const milliseconds = today.getTime();
console.log(milliseconds);
You use the incorrect format. If you get the date from backend you should convert it.
const date = '28.08.2020';
const [day, month, year] = date.split('.');
const validDate = new Date();
validDate.setFullYear(year);
validDate.setDate(day);
validDate.setMonth(month);
// or just
const validDate2 = new Date(year, month, day);
const milliseconds = validDate.getTime();
const milliseconds2 = validDate2.getTime();
console.log(milliseconds)
console.log(milliseconds2)
After this conversion you can use the date as you want
Assuming that you do not want to manually parse the string, you could try to use moment library, which allows one to provide custom dateString patterns used for parsing the date, like demonstrated below
const dateString = '28.08.2020';
const date = moment(dateString, "DD.MM.YYYY");
console.log("date", date); // displayed zulu time might be different than your local timezone
console.log("milliseconds", date.valueOf());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
Please take a note that moment will accept the date in your local timezone, which may pose some issues. If you want to make up for it, you should look up moment-timezone library
Oh, in that case you can change the imput to the "yyyy-mm-dd", is that a posibility?
const date = '28.08.2020';
let dateFromat = date.split('.');
dateFromat = `${dateFromat[2]}-${dateFromat[1]}-${dateFromat[0]}`;
const today = new Date(dateFromat);
const milliseconds = today.getTime();
output: 1598572800000
the dating format is wrong.
new Date('2020-08-28') should work
I have a 'timestamp' value 20200513134950000 and the format should be YYYYMMDDmmhhssuuu.
I can not wrap my head around how to properly format it. I have tried date-fns library and native Date format, but with no luck.
Any ideas?
You can extract all the relevant parts from the number with a simple regexp or even by counting numbers. Then the only caveat is that months are zero-based, but apart from that, you can just use the standard Date() constructor.
const timestamp = 20200513134950000;
const UTC_mask = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{3})/;
const [
year,
month,
day,
hour,
min,
sec,
ms
] = timestamp.toString().match( UTC_mask ).slice( 1 );
const datetime = new Date( year, parseInt( month, 10 ) - 1, day, hour, min, sec, ms );
console.log( datetime );
Without any library you can just get the parts and pass them to the Date constructor:
let ts = '20200513134950000';
let [c,y,m,d,H,M,S] = ts.match(/\d\d/g);
console.log(new Date(c+y,--m,d,H,M,S).toString());
You can try using DayJS.
Its a lightweight library and allows you to specify custom parse format for parsing the dates.
const dayjs = require('dayjs');
var customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
console.log(dayjs('20200513134950000', 'YYYYMMDDmmhhssuuu'))
So, I need to calculate age by subtracting "todays" date from the converted date of an input field, entered by the user. Although it needs cleaned up, the below code works, I had to get creative as RN uses a different JS execution environment... see here.
My question, without adding the "+1" to this snippet "b.getMonth() + 1", the math on the date subtraction comes back 1 month off every time. When I add the "+1" it works like a charm, why? If it's a logical fix, I don't mind keeping the "+1," but I would surely like to know why the "+1" is necessary.
Also, totally open to improved solutions to this problem, keep in mind I had a much simpler function that worked great while debugger was open, once closed, it did not work, see the link above.
getVerifyBirthday(birthday) {
const b = new Date();
var verify = birthday.length;
const utc2 = Date.UTC(b.getFullYear(), b.getMonth() + 1, b.getDate());
if (verify === 10) {
const splitBirth = birthday.split('-');
var mydate = new Date(splitBirth[2], splitBirth[0], splitBirth[1]);
const a = mydate;
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const diffTime = Math.abs(utc2 - utc1);
const diffYears = (diffTime / (3.15576e+10));
this.setState({ diffYears: diffYears});
return diffYears >= 13;
} else {}
}
Update
I ended up refactoring my original function, leaving the (+1) on months due to months starting at 0, as mentioned below. I still had to split both dates, when I didn't split both, my age came back NaN/Undefined; not sure if this goes back to the RN execution environment vs browser, but I digress.
I'd make a few of my own suggestions over here:
there's no need to hussle with UTC dates (to make sure whether the user in his timezone has already reached the age of 13, assuming along the way that he or she was born in that same timezone ;)
there's no need to split mm-dd-yyyy date string to convert into Date, it may be parsed by new Date()
counting years as 365.25 days has certain error margin depending on the exact leap years quantity that passed since the user's birth year, instead whole years may be compared together with dates
To me, it makes more sense to decompose date strings into days, months and years and make decision based on full years difference minus 1 year (if the person didn't yet celebrate his/her birthday this year):
const today = new Date().toISOString().slice(0,10), // yyyy-mm-dd
birthday = '1982-06-21',
[bYear, bMonth, bDay] = birthday.split('-'),
[tYear, tMonth, tDay] = today.split('-'),
diffYears = tYear - bYear - (bMonth > tMonth || bDay > tDay ? 1 : 0)
console.log(diffYears)
.as-console-wrapper{min-height:100%;}
Months are zero-based in JavaScript Date objects. However, if you get a formatted string, they start from 1:
const date = new Date(2020, 1, 17); // 17th of February 2020
console.log("getMonth:", date.getMonth()); //month is 1
console.log("formatted:", date.toISOString()); //month is 2
So, actually what happens is that you're shifting both dates a month forward. This sort of works:
const originDate = new Date(2020, 1, 17); // 17th of February 2020
const originString = "2020-02-17".split("-");
const dateFromDate = new Date(originDate.getFullYear(), originDate.getMonth() + 1, originDate.getDate())
const dateFromString = new Date(originString[0], originString[1], originString[2])
console.log("dateFromDate:", dateFromDate); //month is 3
console.log("dateFromString:", dateFromString); //month is 3
When you do the subtraction it evens out but you can still run into an overflow of the date for months with different number of days:
const originDate = new Date(2020, 0, 31); // 31st of January 2020
const dateFromDate = new Date(originDate.getFullYear(), originDate.getMonth() + 1, originDate.getDate())
console.log("dateFromDate:", dateFromDate); // 1st of March 2020
This still works logically for most cases, however you are bound to run into a problem at some point if you shift months forward. So, instead you should be doing the opposite and subtracting 1 when converting a 1-based number into a Date object:
const originString = "2020-02-17".split("-");
const dateFromString = new Date(originString[0], originString[1] - 1, originString[2])
console.log("dateFromString:", dateFromString); //month is 2