I wanted to calculate common date ranges with moment.js for things like:
* yesterday
* week
* week-to-date
* quarter
* quarter-to-date
etc. I didn't find what I was looking for on Stackoverflow so I thought I would post this for others in case it helps.
// Yesterday
console.log("yesterday", moment().startOf('day').subtract(1, 'day').format('MM-DD-YYYY'), moment().startOf('day').subtract(1, 'day').format('MM-DD-YYYY'));
console.log("");
// Week
console.log("week", moment().startOf('week').format('MM-DD-YYYY'), moment().endOf('week').format('MM-DD-YYYY'));
console.log("week-to-date", moment().startOf('week').format('MM-DD-YYYY'), moment().format('MM-DD-YYYY'));
console.log("prior-week", moment().startOf('week').subtract(1, 'week').format('MM-DD-YYYY'), moment().endOf('week').subtract(1, 'week').endOf('week').format('MM-DD-YYYY'));
console.log("prior-week-to-date", moment().startOf('week').subtract(1, 'week').format('MM-DD-YYYY'), moment().subtract(1, 'week').format('MM-DD-YYYY'));
console.log("prior-year-week", moment().startOf('week').subtract(1, 'year').format('MM-DD-YYYY'), moment().endOf('week').subtract(1, 'year').format('MM-DD-YYYY'));
console.log("prior-year-week-to-date", moment().startOf('week').subtract(1, 'year').format('MM-DD-YYYY'), moment().subtract(1, 'year').format('MM-DD-YYYY'));
console.log("");
// Months
console.log("month", moment().startOf('month').format('MM-DD-YYYY'), moment().endOf('month').format('MM-DD-YYYY'));
console.log("month-to-date", moment().startOf('month').format('MM-DD-YYYY'), moment().format('MM-DD-YYYY'));
console.log("prior-month", moment().startOf('month').subtract(1, 'month').format('MM-DD-YYYY'), moment().endOf('month').subtract(1, 'month').endOf('month').format('MM-DD-YYYY'));
console.log("prior-month-to-date", moment().startOf('month').subtract(1, 'month').format('MM-DD-YYYY'), moment().subtract(1, 'month').format('MM-DD-YYYY'));
console.log("prior-year-month", moment().startOf('month').subtract(1, 'year').format('MM-DD-YYYY'), moment().endOf('month').subtract(1, 'year').format('MM-DD-YYYY'));
console.log("prior-year-month-to-date", moment().startOf('month').subtract(1, 'year').format('MM-DD-YYYY'), moment().subtract(1, 'year').format('MM-DD-YYYY'));
console.log("");
// Quarters
console.log("quarter", moment().startOf('quarter').format('MM-DD-YYYY'), moment().endOf('quarter').format('MM-DD-YYYY'));
console.log("quarter-to-date", moment().startOf('quarter').format('MM-DD-YYYY'), moment().format('MM-DD-YYYY'));
console.log("prior-quarter", moment().startOf('quarter').subtract(1, 'quarter').format('MM-DD-YYYY'), moment().endOf('quarter').subtract(1, 'quarter').endOf('quarter').format('MM-DD-YYYY'));
console.log("prior-quarter-to-date", moment().startOf('quarter').subtract(1, 'quarter').format('MM-DD-YYYY'), moment().subtract(1, 'quarter').format('MM-DD-YYYY'));
console.log("prior-year-quarter", moment().startOf('quarter').subtract(1, 'year').format('MM-DD-YYYY'), moment().endOf('quarter').subtract(1, 'year').endOf('quarter').format('MM-DD-YYYY'));
console.log("prior-year-quarter-to-date", moment().startOf('quarter').subtract(1, 'year').format('MM-DD-YYYY'), moment().subtract(1, 'year').format('MM-DD-YYYY'));
console.log("");
// years
console.log("year", moment().startOf('year').format('MM-DD-YYYY'), moment().endOf('year').format('MM-DD-YYYY'));
console.log("year-to-date", moment().startOf('year').format('MM-DD-YYYY'), moment().format('MM-DD-YYYY'));
console.log("prior-year", moment().startOf('year').subtract(1, 'year').format('MM-DD-YYYY'), moment().endOf('year').subtract(1, 'year').endOf('year').format('MM-DD-YYYY'));
console.log("prior-year-to-date", moment().startOf('year').subtract(1, 'year').format('MM-DD-YYYY'), moment().subtract(1, 'year').format('MM-DD-YYYY'));
console.log("");
Related
I'm looking for a way to use DateTime to parse two dates, to show the difference.
I want to have it on the format: "X years, Y months, Z days".
For JS, we have momentjs library and following code::
var a = moment([2015, 11, 29]);
var b = moment([2007, 06, 27]);
var years = a.diff(b, 'year');
b.add(years, 'years');
var months = a.diff(b, 'months');
b.add(months, 'months');
var days = a.diff(b, 'days');
console.log(years + ' years ' + months + ' months ' + days + ' days');
// 8 years 5 months 2 days
Is there similar library available for dart that can help achieve this usecase?
I think it is not possible to do exactly what you want easily with DateTime. Therefore you can use https://pub.dev/packages/time_machine package that is quite powerful with date time handling:
import 'package:time_machine/time_machine.dart';
void main() {
LocalDate a = LocalDate.today();
LocalDate b = LocalDate.dateTime(DateTime(2022, 1, 2));
Period diff = b.periodSince(a);
print("years: ${diff.years}; months: ${diff.months}; days: ${diff.days}");
}
for hours/minutes/seconds precision:
import 'package:time_machine/time_machine.dart';
void main() {
LocalDateTime a = LocalDateTime.now();
LocalDateTime b = LocalDateTime.dateTime(DateTime(2022, 1, 2, 10, 15, 47));
Period diff = b.periodSince(a);
print("years: ${diff.years}; months: ${diff.months}; days: ${diff.days}; hours: ${diff.hours}; minutes: ${diff.minutes}; seconds: ${diff.seconds}");
}
What you are looking for is the Dart DateTime class
You can get close to what you want in moment.js with
main() {
var a = DateTime.utc(2015, 11, 29);
var b = DateTime.utc(2007, 06, 27);
var years = a.difference(b);
print(years.inDays ~/365);
}
There is no inYears or inMonths option for DateTime though that's why the year is divided in the print.
the difference function returns the difference in seconds so you have to process it yourself to days.
You could write an extension on duration class to format it:
extension DurationExtensions on Duration {
String toYearsMonthsDaysString() {
final years = this.inDays ~/ 365
// You will need a custom logic for the months part, since not every month has 30 days
final months = (this.inDays ~% 365) ~/ 30
final days = (this.inDays ~% 365) ~% 30
return "$years years $months months $days days";
}
}
The usage will be:
final date1 = DateTime()
final date2 = DateTime()
date1.difference(date2).toYearsMonthsDaysString()
You can use Jiffy Package for this like this
var jiffy1 = Jiffy("2008-10", "yyyy-MM");
var jiffy2 = Jiffy("2007-1", "yyyy-MM");
jiff1.diff(jiffy2, Units.YEAR); // 1
jiff1.diff(jiffy2, Units.YEAR, true);
You can calculate from the total number of days:
void main() {
DateTime a = DateTime(2015, 11, 29);
DateTime b = DateTime(2007, 06, 27);
int totalDays = a.difference(b).inDays;
int years = totalDays ~/ 365;
int months = (totalDays-years*365) ~/ 30;
int days = totalDays-years*365-months*30;
print("$years $months $days $totalDays");
}
Result is: 8 5 7 3077
I created my own class for Gregorian Dates, and I created a method which handle this issue, it calculates "logically" the difference between two dates in years, months, and days...
i actually created the class from scratch without using any other packages (including DateTime package) but here I used DateTime package to illustrate how this method works.. until now it works fine for me...
method to determine if it's a leap year or no:
static bool leapYear(DateTime date) {
if(date.year%4 == 0) {
if(date.year%100 == 0){
return date.year%400 == 0;
}
return true;
}
return false;
}
this is the method which calculates the difference between two dates in years, months, and days. it puts the result in a list of integers:
static List<int> differenceInYearsMonthsDays(DateTime dt1, DateTime dt2) {
List<int> simpleYear = [31,28,31,30,31,30,31,31,30,31,30,31];
if(dt1.isAfter(dt2)) {
DateTime temp = dt1;
dt1 = dt2;
dt2 = temp;
}
int totalMonthsDifference = ((dt2.year*12) + (dt2.month - 1)) - ((dt1.year*12) + (dt1.month - 1));
int years = (totalMonthsDifference/12).floor();
int months = totalMonthsDifference%12;
late int days;
if(dt2.day >= dt1.day) {days = dt2.day - dt1.day;}
else {
int monthDays = dt2.month == 3
? (leapYear(dt2)? 29: 28)
: (dt2.month - 2 == -1? simpleYear[11]: simpleYear[dt2.month - 2]);
int day = dt1.day;
if(day > monthDays) day = monthDays;
days = monthDays - (day - dt2.day);
months--;
}
if(months < 0) {
months = 11;
years--;
}
return [years, months, days];
}
the method which calculates the difference between two dates in months, and days:
static List<int> differenceInMonths(DateTime dt1, DateTime dt2){
List<int> inYears = differenceInYearsMonthsDays(dt1, dt2);
int difMonths = (inYears[0]*12) + inYears[1];
return [difMonths, inYears[2]];
}
the method which calculates the difference between two dates in days:
static int differenceInDays(DateTime dt1, DateTime dt2) {
if(dt1.isAfter(dt2)) {
DateTime temp = dt1;
dt1 = dt2;
dt2 = temp;
}
return dt2.difference(dt1).inDays;
}
usage example:
void main() {
DateTime date1 = DateTime(2005, 10, 3);
DateTime date2 = DateTime(2022, 1, 12);
List<int> diffYMD = GregorianDate.differenceInYearsMonthsDays(date1, date2);
List<int> diffMD = GregorianDate.differenceInMonths(date1, date2);
int diffD = GregorianDate.differenceInDays(date1, date2);
print("The difference in years, months and days: ${diffYMD[0]} years, ${diffYMD[1]} months, and ${diffYMD[2]} days.");
print("The difference in months and days: ${diffMD[0]} months, and ${diffMD[1]} days.");
print("The difference in days: $diffD days.");
}
output:
The difference in years, months and days: 16 years, 3 months, and 9 days.
The difference in months and days: 195 months, and 9 days.
The difference in days: 5945 days.
the answer is yes, you can easilly achieve it with DateTime class in Dart. See: https://api.dart.dev/stable/2.8.3/dart-core/DateTime-class.html
Example
void main() {
var moonLanding = DateTime(1969,07,20)
var marsLanding = DateTime(2024,06,10);
var diff = moonLanding.difference(marsLanding);
print(diff.inDays.abs());
print(diff.inMinutes.abs());
print(diff.inHours.abs());
}
outputs:
20049
28870560
481176
final firstDate = DateTime.now();
final secondDate = DateTime(firstDate.year, firstDate.month - 20);
final yearsDifference = firstDate.year - secondDate.year;
final monthsDifference = (firstDate.year - secondDate.year) * 12 +
firstDate.month - secondDate.month;
final totalDays = firstDate.difference(secondDate).inDays;
Simple approach, no packages needed.
try intl package with the following code:
import 'package:intl/intl.dart';
String startDate = '01/01/2021';
String endDate = '01/01/2022';
final start = DateFormat('dd/MM/yyyy').parse(startDate);
final end = DateFormat('dd/MM/yyyy').parse(endDate);
Then, you can calculate the duration between the two dates with the following code:
final duration = end.difference(start);
To obtain the number of years, months and days, you can do the following:
final years = duration.inDays / 365;
final months = duration.inDays % 365 / 30;
final days = duration.inDays % 365 % 30;
Finally, you can use these variables to display the result in the desired format:
final result = '${years.toInt()} years ${months.toInt()} months y ${days.toInt()} days';
DateTime difference in years is a specific function, like this:
static int getDateDiffInYear(DateTime dateFrom, DateTime dateTo) {
int sign = 1;
if (dateFrom.isAfter(dateTo)) {
DateTime temp = dateFrom;
dateFrom = dateTo;
dateTo = temp;
sign = -1;
}
int years = dateTo.year - dateFrom.year;
int months = dateTo.month - dateFrom.month;
if (months < 0) {
years--;
} else {
int days = dateTo.day - dateFrom.day;
if (days < 0) {
years--;
}
}
return years * sign;
}
difHour = someDateTime.difference(DateTime.now()).inHours;
difMin = (someDateTime.difference(DateTime.now()).inMinutes)-(difHour*60);
and same for years and days
in flutter we can get current month using this
var now = new DateTime.now();
var formatter = new DateFormat('MM');
String month = formatter.format(now);
But how to get the last month date? Especially if current date is January (01). we can't get the right month when we use operand minus (-) , like month - 1.
You can just use
var prevMonth = new DateTime(date.year, date.month - 1, date.day);
with
var date = new DateTime(2018, 1, 13);
you get
2017-12-13
It's usually a good idea to convert to UTC and then back to local date/time before doing date calculations to avoid issues with daylight saving and time zones.
We can calculate both first day of the month and the last day of the month:
DateTime firstDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month, 1);
DateTime lastDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month + 1).subtract(Duration(days: 1));
DateTime.utc takes in integer values as parameters: int year, int month, int day and so on.
Try this package, Jiffy, it used momentjs syntax. See below
Jiffy().subtract(months: 1);
Where Jiffy() returns date now. You can also do the following, the same result
var now = DateTime.now();
Jiffy(now).subtract(months: 1);
We can use the subtract method to get past month date.
DateTime pastMonth = DateTime.now().subtract(Duration(days: 30));
Dates are pretty hard to calculate. There is an open proposal to add support for adding years and months here https://github.com/dart-lang/sdk/issues/27245.
There is a semantic problem with adding months and years in that "a
month" and "a year" isn't a specific amount of time. Years vary by one
day, months by up to three days. Adding "one month" to the 30th of
January is ambiguous. We can do it, we just have to pick some
arbitrary day between the 27th of February and the 2nd of March.
That's why we haven't added month and year to Duration - they do not
describe durations.
You can use the below code to add months in a arbitrary fashion (I presume its not completely accurate. Taken from the issue)
const _daysInMonth = const [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
bool isLeapYear(int value) =>
value % 400 == 0 || (value % 4 == 0 && value % 100 != 0);
int daysInMonth(int year, int month) {
var result = _daysInMonth[month];
if (month == 2 && isLeapYear(year)) result++;
return result;
}
DateTime addMonths(DateTime dt, int value) {
var r = value % 12;
var q = (value - r) ~/ 12;
var newYear = dt.year + q;
var newMonth = dt.month + r;
if (newMonth > 12) {
newYear++;
newMonth -= 12;
}
var newDay = min(dt.day, daysInMonth(newYear, newMonth));
if (dt.isUtc) {
return new DateTime.utc(
newYear,
newMonth,
newDay,
dt.hour,
dt.minute,
dt.second,
dt.millisecond,
dt.microsecond);
} else {
return new DateTime(
newYear,
newMonth,
newDay,
dt.hour,
dt.minute,
dt.second,
dt.millisecond,
dt.microsecond);
}
}
To get a set starting point at the start of a month, you can use DateTime along with the Jiffy package.
DateTime firstOfPreviousMonth
= DateTime.parse(
Jiffy().startOf(Units.MONTH)
.subtract(months: 1)
.format('yyyy-MM-dd'). //--> Jan 1 '2021-01-01 00:00:00.000'
);
var fifthOfMonth
= firstOfPreviousMonth.add(Duration(days: 4)); //--> Jan 5 '2021-01-05 00:00:00.000'
or
DateTime endOfPreviousMonth
= DateTime.parse(
Jiffy().endOf(Units.MONTH)
.subtract(months: 2)
.format('yyyy-MM-dd'). //--> Dec 30 '2020-12-31 00:00:00.000'
// endOf always goes to 30th
);
var previousMonth
= endOfPreviousMonth.add(Duration(days: 2)); //--> Jan 1 '2021-01-01 00:00:00.000'
DateFormat('MMMM yyyy')
.format(DateTime(DateTime.now().year, DateTime.now().month - 2)),
List<DateTime> newList = [];
DateFormat format = DateFormat("yyyy-MM-dd");
for (var i = 0; i < recents.length; i++) {
newList.add(format.parse(recents[i]['date'].toString()));
}
newList.sort(((a, b) => a.compareTo(b)));
var total = 0;
for (var i = 0; i < newList.length; i++) {
if (DateTime.now().difference(newList[i]).inDays < 30) {
print(newList[i]);
total++;
}
}
print(total);
You can use this to fetch the last 30 days.
In addition to Günter Zöchbauer Answer
var now = new DateTime.now();
String g = ('${now.year}/ ${now.month}/ ${now.day}');
print(g);
I would like to subtract days from the current date in TypeScript.
For example, if the current date is October 1st, 2017, I would like to subtract 1 day to get September 30th, 2017, or if I want to subtract 3 days I would get September 28th etc.
This is what I have so far, the result is I received December 31st, 1969. Which I assume means that tempDate.getDate() is returning zero, as in the Epoch of January 1, 1970.
This is my code, the goal is to return the previous working day.
protected generateLastWorkingDay(): Date {
var tempDate = new Date(Date.now());
var day = tempDate.getDay();
//** if Monday, return Friday
if (day == 1) {
tempDate = new Date(tempDate.getDate() - 3);
} else if (1 < day && day <= 6) {
tempDate = new Date(tempDate.getDate() - 1);
}
return tempDate;
}
getDate returns the date of the month (1-31), so creating a new Date from it treats that number as "milliseconds since epoch".
What you probably want is to use setDate to change the date as it automatically handled going backwards through months/years.
protected generateLastWorkingDay(): Date {
const lastWorkingDay = new Date();
while(!this.isWorkingDay(lastWorkingDay)) {
lastWorkingDay.setDate(lastWorkingDay.getDate()-1);
}
return lastWorkingDay;
}
private isWorkingDay(date: Date) {
const day = date.getDay();
const isWeekday = (day > 0 && day < 6);
return isWeekday; // && !isPublicHoliday?
}
This is how I did
let yesterday=new Date(new Date().getTime() - (1 * 24 * 60 * 60 * 1000));
let last3days=new Date(new Date().getTime() - (3 * 24 * 60 * 60 * 1000));
We need to minus (no_of_days) * 24 * 60 * 60 * 1000 from current date.
You can just
const current = new Date()
and then
const numberOfDaysToSubstract= 3;
const prior = new Date().setDate(current.getDate) - numberOfDaysToSubstract);
you can see an example of this here
https://codepen.io/Jeysoon/pen/poNZRwd?editors=1112
I am using fullcalendar plugin to get and display holidays of a month via Ajax. The problem I am having, is that the method that retrieves the holidays accepts only a year and a month as parameter, not a date range.
When using month view of fullcalendar, the start and end parameter ranges from feb 23rd and Apr 6th. I need it to range from Mar 1st to Mar 31st. That way, I can only get year and month part to call the method.
This is what I tried but without success:
$('#calendar').fullCalendar({
monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
monthNamesShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
dayNames: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
dayNamesShort: ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'],
events: '/get_month_holidays',
start: {
month: new Date((new Date()).getFullYear(), (new Date()).getMonth(), 1)
},
end: {
month: (new Date((new Date()).getFullYear(), (new Date()).getMonth() + 1, 1)) - 1
},
buttonText: {
today: 'hoy'
}
})
Any help will be appreciated,
Thanks
Jaime
Finally I used:
eventSources: [
{
url: '/get_month_holidays',
type: 'POST',
data: function() {
var fecha = $('#calendar').fullCalendar('getDate');
return {
month: fecha.getMonth() + 1,
year: fecha.getFullYear()
}
}
}
],
And it worked. Thanks anyway.
Jaime
jstuardo's solution adds new parameters to the request so you end up with something like this:
http://your.api.com/events?month=8&year=2015&start=2015-07-27&end=2015-09-07
Which is quite confusing and requires you to change the API accordingly.
Better solution would be to change the default start and end parameters. You can achieve that using something like this:
{
url: baseUrl + '/events',
startParam: null, //resetting default fullcalendar parameter
endParam: null, //resetting default fullcalendar parameter
data: function() {
var date = $('#gc-calendar').fullCalendar('getDate')._d;
var firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
firstDay = $filter('date')(firstDay, 'yyyy-MM-dd');
lastDay = $filter('date')(lastDay, 'yyyy-MM-dd');
//AngularJS way of changing the date format to yyyy-mm-dd
return {
start: firstDay,
end: lastDay
}
}
}
This way your request looks like this:
http://your.api.com/calendar_orders?start=2015-08-01&end=2015-08-31
You can format the date to 'yyy-MM-dd' using any method you like. You can find a bunch of them here:
Get String in YYYYMMDD format from JS date object?
Here is the code I am trying
public static const millisecondsPerDay:int = 1000 * 60 * 60 * 24
var sixMonthsInMilis:int = 182 * millisecondsPerDay;
var sixMonthsInTheFuture:Date = new Date();
sixMonthsInTheFuture.setTime(sixMonthsInTheFuture.getTime() + sixMonthsInMilis );
var sixMonthsInThePast:Date = new Date();
sixMonthsInThePast.setTime(sixMonthsInThePast.getTime() - sixMonthsInMilis);
The one thats meant to be in the past is a few days in the future, the other a few days in the past. A far cry from the 6 months I am after
Any Ideas?
var today:Date = new Date();
today.setMonth(today.getMonth() + 6);
var sixMonthsInTheFuture:Date = today;
var anotherToday:Date = new Date();
anotherToday.setMonth(anotherToday.getMonth() - 6);
var sixMonthsInThePast:Date = anotherToday;
trace(sixMonthsInTheFuture);
trace(sixMonthsInThePast);
For me, this returns
Mon May 28 14:03:32 GMT+0530 2012
Sat May 28 14:03:32 GMT+0530 2011
Which seems fair enough, right?
Um... var
var now:Date = new Date();
now.setMonth(now.getMonth() + 6);
var sixMonthsInTheFuture:Date = now;
var now:Date = new Date();
now.setMonth(now.getMonth() - 6);
var sixMonthsInThePast:Date = now;
Not sure if this would work 100%, as I'm not sure if Flex does date overflowing, (Like, would September + 6 be January the next year?), some languages do. Try it out
Apparently setMonth also takes a second paramater, Day, which is day number between 1 and 31, so some more ifs to check date and if it's more than the largest day of the new month etc., but this is the general idea