Convert moment.js to date-fns - javascript

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);

Related

Invalid Date with datejs

I need to convert string to date.
But I don't understand why the end date is not converted from a string. Then I decided to use the daysJs library, but it gave the same thing
let date={
end:"15-10-2022",
start:"05-10-2022",
}
let range = {
start:new Date(date.start),
end: new Date(date.end),
};
console.log(range)
Running the code snippet embedded in Stack, I can see that your end property is null, presumably because the formattign for the dates is MM-DD-YYYY and you're formatting them as DD-MM-YYYY. The simplest solution is to Swap your month and day in the date. Otherwise, just use MomentJS for its simplification of working with dates.
Formatting DD-MM-YYYY without moment:
let date = {
end: '15-10-2022',
start: '05-10-2022'
};
let range = {
start: new Date(date.start.split('-').reverse().join('-')),
end: new Date(date.end.split('-').reverse().join('-'))
};
console.log(range);
Formatting DD-MM-YYYY with moment:
let date = {
end: '15-10-2022',
start: '05-10-2022'
};
let range = {
start: moment(date.start, 'DD-MM-YYYY'),
end: moment(date.end, 'DD-MM-YYYY')
};
console.log(range);
first number is month so 15 is undefined
let date={
end:"10-10-2022",
start:"05-10-2022",
}
let range = {
start:new Date(date.start),
end: new Date(date.end),
};
console.log(range)
The date format is wrong. Use YYYY-MM-DD

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>

How can I say "Today" and Yesterday" with Moment? [duplicate]

I'd like the moment().fromNow() functionality, but when the date is close it is too precise - ex. I don't want it to show 'in 3 hours' but 'today' - so basically with a 'daily' precision.
I tried using the moment().calendar() function, it doesn't format if the date difference is more than 1 day
You can also do this to get the date for today and tomorrow and yesterday
let today = moment();
let tomorrow = moment().add(1,'days');
let yesterday = moment().add(-1, 'days');
I use a combination of add() and endOf() with moment
//...
const today = moment().endOf('day')
const tomorrow = moment().add(1, 'day').endOf('day')
if (date < today) return 'today'
if (date < tomorrow) return 'tomorrow'
return 'later'
//...
[EDIT 2022-01-04] I suggest you to use now dayjs which has the very same API as moment and is lightweight ;)
You can customize the way that both the .fromNow and the .calendar methods display dates using moment.updateLocale. The following code will change the way that .calendar displays as per the question:
moment.updateLocale('en', {
calendar : {
lastDay : '[Yesterday]',
sameDay : '[Today]',
nextDay : '[Tomorrow]',
lastWeek : '[Last] dddd',
nextWeek : '[Next] dddd',
sameElse : 'L'
}
});
Based on the question, it seems like the .calendar method would be more appropriate -- .fromNow wants to have a past/present prefix/suffix, but if you'd like to find out more you can read the documentation at http://momentjs.com/docs/#/customization/relative-time/.
To use this in only one place instead of overwriting the locales, pass a string of your choice as the first argument when you define the moment.updateLocale and then invoke the calendar method using that locale (eg. moment.updateLocale('yesterday-today').calendar( /* moment() or whatever */ ))
EDIT: Moment ^2.12.0 now has the updateLocale method. updateLocale and locale appear to be functionally the same, and locale isn't yet deprecated, but updated the answer to use the newer method.
Requirements:
When the date is further away, use the standard moment().fromNow() functionality.
When the date is closer, show "today", "yesterday", "tomorrow", etc.
Solution:
// call this function, passing-in your date
function dateToFromNowDaily( myDate ) {
// get from-now for this date
var fromNow = moment( myDate ).fromNow();
// ensure the date is displayed with today and yesterday
return moment( myDate ).calendar( null, {
// when the date is closer, specify custom values
lastWeek: '[Last] dddd',
lastDay: '[Yesterday]',
sameDay: '[Today]',
nextDay: '[Tomorrow]',
nextWeek: 'dddd',
// when the date is further away, use from-now functionality
sameElse: function () {
return "[" + fromNow + "]";
}
});
}
NB: From version 2.14.0, the formats argument to the calendar function can be a callback, see http://momentjs.com/docs/#/displaying/calendar-time/.
You can use this:
const today = moment();
const tomorrow = moment().add(1, 'days');
const yesterday = moment().subtract(1, 'days');
Here is how I do that using moment:
let today = moment().format('DD MMMM YYYY');
let tomorrow = moment().add(1, 'days').format('DD MMMM YYYY').toString();
let yesterday = moment().subtract(1, 'days').startOf('day').format('DD MMMM YYYY').toString();
I have similar solution, but allows to use locales:
let date = moment(someDate);
if (moment().diff(date, 'days') >= 2) {
return date.fromNow(); // '2 days ago' etc.
}
return date.calendar().split(' ')[0]; // 'Yesterday', 'Today', 'Tomorrow'
From 2.10.5 moment supports specifying calendar output formats per invocation
For a more detailed documentation check Moment - Calendar.
**Moment 2.10.5**
moment().calendar(null, {
sameDay: '[Today]',
nextDay: '[Tomorrow]',
nextWeek: 'dddd',
lastDay: '[Yesterday]',
lastWeek: '[Last] dddd',
sameElse: 'DD/MM/YYYY'
});
From 2.14.0 calendar can also take a callback to return values.
**Moment 2.14.0**
moment().calendar(null, {
sameDay: function (now) {
if (this.isBefore(now)) {
return '[Will Happen Today]';
} else {
return '[Happened Today]';
}
/* ... */
}
});
In Moment.js, the from() method has the daily precision you're looking for:
var today = new Date();
var tomorrow = new Date();
var yesterday = new Date();
tomorrow.setDate(today.getDate()+1);
yesterday.setDate(today.getDate()-1);
moment(today).from(moment(yesterday)); // "in a day"
moment(today).from(moment(tomorrow)); // "a day ago"
moment(yesterday).from(moment(tomorrow)); // "2 days ago"
moment(tomorrow).from(moment(yesterday)); // "in 2 days"
So this is what I ended up doing
var dateText = moment(someDate).from(new Date());
var startOfToday = moment().startOf('day');
var startOfDate = moment(someDate).startOf('day');
var daysDiff = startOfDate.diff(startOfToday, 'days');
var days = {
'0': 'today',
'-1': 'yesterday',
'1': 'tomorrow'
};
if (Math.abs(daysDiff) <= 1) {
dateText = days[daysDiff];
}
You can use .add() and .subtract() method to get yesterday and tomorrow date. Then use format method to get only date .format("D/M/Y"), D stand for Day, M for Month, Y for Year. Check in Moment Docs
let currentMilli = Date.now()
let today = Moment(currentMilli).format("D/M/Y");
let tomorrow = Moment(currentMilli).add(1, 'days').format("D/M/Y");
let yesterday = Moment(currentMilli).subtract(1, 'days').format("D/M/Y");
Result will be:
Current Milli - 1576693800000
today - 19/12/2019
tomorrow - 18/12/2019
yesterday - 18/12/2019
const date = moment(YOUR_DATE)
return (moment().diff(date, 'days') >= 2) ? date.fromNow() : date.calendar().split(' ')[0]
Add Past and future date in Date time picker in react-native
import DateTimePickerModal from "react-native-modal-datetime-picker";
import moment from 'moment';
let addFutureDay = new Date();
addFutureDay = moment(addFutureDay).add(2, 'day').format('MM/DD/YYYY');
const FutureMonthAdd = moment(addFutureDay, 'MM/DD/YYYY').toDate();
let addPastDate = new Date();
addPastDate = moment(addPastDate).add(-2, 'day').format('MM/DD/YYYY');
const PastMonthAdd = moment(addPastDate, 'MM/DD/YYYY').toDate();
return (
<View>
<Text> DatePickerDemo </Text>
<Button title="Show Date Picker" onPress={showDatePicker} />
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
minimumDate={PastMonthAdd}
maximumDate={FutureMonthAdd}
onConfirm={handleConfirm}
onCancel={hideDatePicker}
/>
</View>
)
const formatedDate= moment(date).format("DD-MM-YYYY hh:mm:ss a")
const formatedDate2= moment(date).format("DD-MM-YYYY hh:mm A") // DD-MM-YYYY hh:mm a

Moment.Js calculate difference datetime and show result

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>

set the starting month as 0 instead of 1 ngb datepicker

I am using Datepicker control https://ng-bootstrap.github.io/#/components/datepicker/overview. I am using CustomDateParserFormatter to parse the date to different format. My issue is I am using dayjs to transform the dates which intern returns the date as the javascript object which means month will returned from 0 to 11, in that case datepicker shown november in the month dropdown if I enter 12/12/2012. Is there anywhere in the datepicker I can mention that the month starts from 0 and not 1 ? right now I am adding subtracting month which doesn't look clean.
current custom parser
parse(value: string | null): NgbDateStruct | any {
const dateFormat = 'MM/DD/YYYY';
if (value) {
const otherthing = dayjs(value).format(dateFormat);
const tests = dayjs(otherthing);
const something = {
day: tests.date(),
month: tests.month() + 1,
year: tests.year(),
};
return something;
}
return null;
}
format(date: NgbDateStruct): string {
if (date) {
const something = dayjs(new Date(date.year, date.month - 1, date.day));
return something.format('MM/DD/YYYY');
}
return '';
}

Categories

Resources