Adding days to a date using std.datetime - date

Why are you not allowed to add days to a date in std.datetime? You can add months and years, but not days.
Recently I had to calculate a date for Easter Sunday, then I had to calculate related holidays (Ascension, Pentecost, Trinity, Corpus) by adding a certain number of days (39, 10, 7, 4) to the last date.
I ended up using dayOfYear:
date.dayOfYear(date.dayOfYear + offset);
This worked well, but only because I remained within the same year. What if I have to add 50 days to, say, dec 28?
Is there an easy way of doing this that I have overlooked?

You can use Duration from core.time.
Importing std.datetime will import core.time, so you can use it directly as follows.
import std.stdio, std.datetime;
void main() {
auto date = Date(2013, 12, 28);
writefln("%s + %s = %s", date, 10.days(), date + 10.days());
}
BTW, days() is an alias to dur!"days"() which constructs a Duration struct.
Check the documentation of core.time http://dlang.org/phobos/core_time.html for more information.

If you haven't read this article on std.datetime yet, then you probably should, as it will probably answer most basic questions that you have for how to use it.
But in general, core.time.Duration is what you should be using for adding and subtracting units from any of the time point types in std.datetime (SysTime, DateTime, Date, or TimeOfDay). So, you get code like
auto date = Date(2012, 12, 21);
date += dur!"days"(50);
or
auto date = Date(2012, 12, 21);
date += days(50);
(The templated dur function is the generic way to generate a Duration, but it has aliases for each of the units that it supports, so stuff like seconds(5) or 22.minutes() will work as well).
The add function exists for "months" and "years", because a Duration can't hold months or years (because you can't convert between them and smaller units without a specific date), and there needs to be a way to add months or years to a time point. Also, there's the question of what to do when you add or subtract a month or year to/from a date, and the month that it moves to doesn't include that day, so add accepts AllowDayOverflow in order to control that (which wouldn't be necessary with smaller units).
auto d3 = Date(2000, 2, 29);
d3.add!"years"(1);
assert(d3 == Date(2001, 3, 1));
auto d4 = Date(2000, 2, 29);
d4.add!"years"(1, AllowDayOverflow.no);
assert(d4 == Date(2001, 2, 28));
But add doesn't accept any other units, because you can simply use the normal arithmetic operations with a Duration. Also, subtracting two time points will result in a Duration.
assert(Date(2012, 12, 5) - Date(2002, 11, 17) == dur!"days"(3671));
assert(Date(2012, 12, 5) - dur!"days"(3671) == Date(2002, 11, 17));
Unlike add, roll accepts all of the units in the type rather than just "months" and "years", but that's because it's doing a different operation from +, and so adding or subtracting a Duration won't work (as that already adds or subtracts). Rather roll adds to a specific unit without adding to the others.
auto d = Date(2010, 1, 1);
d.roll!"days"(33);
assert(d == Date(2010, 1, 3));

You can useroll method:
date.roll!"days"(50);

I did overlook it: you can use dayOfGregorianCal:
import std.stdio, std.datetime;
void main() {
auto d = Date(2012, 12, 28);
writeln(d); // 2012-Dec-28
d.dayOfGregorianCal(d.dayOfGregorianCal + 50);
writeln(d); // 2013-Feb-16
}

Related

How to reduce a list to earliest/latest DateTime items in Dart- you know the fun type of code problem

I have a list of DateTime items, I want to get the earliest and latest items in that list for initializing a date range picker with min/max values based on the available data in db.
I have a tough time tracking the "behind the scenes" in loops and the reduce operator. So I'm looking for any help in making this happen efficiently, cause I'm sure I can make this happen inefficiently with 10 loops :P
What I've tried so far, random stuff that obviously is way off. Double loops and looping with reduce and .isbefore or .isAfter. Can't figure this out. My code below is a hodgepodge but it's where I'm at now. I guess another option is to simple order the list by date and take first and last, but I want to see the best solution and I think this is the right place to ask.
This is what I'm trying to apply.
List<DateTime> dateList = [
DateTime(2021, 7, 30),
DateTime(2021, 6, 25),
DateTime(2021, 5, 14),
DateTime(2021, 4, 2),
DateTime(2021, 3, 12),
DateTime(2021, 3, 21)
];
List<DateTime> databaseDateRange() {
var databaseDateRange = <DateTime>[];
for (var item in dateList) {
dateList.reduce((value, element) {
if (value.isAfter(item)) {
databaseDateRange.add(value.xAxis);
}
});
}
return databaseDateRange;
}
print(dateList.reduce((min, e) => e.isBefore(min)? e : min));
In order to get the minimum in the list (i.e earliest date) you can do as #the38amorim said.
I.e
print(dateList.reduce((min, e) => e.isBefore(min) ? e : min));
The above iterates through each one and checks whether the new value is before the saved one, and replaces it if that is the case, otherwise keeps the old one.
For maximum value in the list (i.e latest date), you can conversely do:
print(dateList.reduce((min, e) => e.isAfter(min) ? e : min));
More on reduce here: https://api.dart.dev/stable/2.18.1/dart-core/Iterable/reduce.html

Rounding seconds of time with HH:MM:SS format to nearest minute

For Example: Sunset-Sunrise.org provides sunset/sunrise time with HH:MM:SS format.
Given a time such as 12:53:57, I want to round the seconds to 12:54:00. Please advise.
A general technique for rounding is to add half of the unit you want to round to and then truncating. For example, if you want to round an integer to the nearest ten's digit, you can add 5 and discard the one's digit: ((x + 5) ~/ 10) * 10.
The same technique works for times too. You can first parse the HH:MM:SS string into a DateTime object. Then, to round the DateTime to the nearest minute, you can add 30 seconds and copy all of the resulting fields except for the seconds (and subseconds):
DateTime roundToMinute(DateTime dateTime) {
dateTime = dateTime.add(const Duration(seconds: 30));
return (dateTime.isUtc ? DateTime.utc : DateTime.new)(
dateTime.year,
dateTime.month,
dateTime.day,
dateTime.hour,
dateTime.minute,
);
}
You can use date_time_fromat packages
from the docs
final timeOffset = dateTime.subtract(Duration(hours: 6, minutes: 45));
// 7 hours
print(DateTimeFormat.relative(timeOffset));
// 6 hours
print(DateTimeFormat.relative(timeOffset, round: false));
This is the URL

UWP calendar view visible date range

I would like to know how to get the range of dates the user is able to see on the Universal Windows Platform CalendarView control. I already tried looking on the Microsoft website but i can't seem to find anything.
1. By default, the minimum date shown in the CalendarView is 100 years prior to the current date, and the maximum date shown is 100 years past the current date.
You can change the minimum and maximum dates that the calendar shows by setting the MinDate and MaxDate properties. For example like this:
calendarView.MinDate = new DateTime(2000, 1, 1);
calendarView.MaxDate = new DateTime(2099, 12, 31);
You can also get the range of dates like this:
var minDate = calendarView.MinDate;
var maxDate = calendarView.MaxDate;
2. If what you want to do is changing the visible region of the CalendarView (by default it starts with the month view open, it shows 6 rows of dates which contain the current month.), you can use CalendarView.SetDisplayDate method for example like this:
DateTime localTime = new DateTime(2007, 07, 12, 06, 32, 00);
DateTimeOffset dateAndOffset = new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime));
calendarView.SetDisplayDate(dateAndOffset);
In this sample, the CalendarView will show the month 2007/7.
3. As I said, by default the number of weeks shown in the calendar view is 6, you can change it by CalendarView.NumberOfWeeksInView property, for example in xaml code:
<CalendarView x:Name="calendarView" NumberOfWeeksInView="8" />
Or code behind:
calendarView.NumberOfWeeksInView = 8;
The minimum number of weeks to show is 2, the maximum is 8;
4. Besides the month view, there are also year view and decade view in CalendarView, you can change it with CalendarView.DisplayMode property for example in xaml code:
<CalendarView x:Name="calendarView" DisplayMode="Year"/>
Or in code behind:
calendarView.DisplayMode = CalendarViewDisplayMode.Decade;
Since you asked a quite simple but broad question, I list every possibilities I could think about. If you have any other questions about this control, please check CalendarView class again.

Compare the duration of dates with selected dropdown value...read please

I have the Drop down with values as "One year ", "Two year",...etc.. Ok? also i have two ajax textbox with calender extender . I want to popup alert message if dropdown selected value is "One year" and duration between the both textbox value Means dates not matches. getting what i mean ? please help me.
Algorithm :
1.Get the both date from the text box.
2. The find the epcoch time for each date. //
3. subtract the both dates.
4. subtract_result = 365*24*60*60 // Finding the 1 year timestamp values
5. So, it the difference exceed than above calculation , you could sure that the date is mis matching.
// This is for first date
first = new Date(2010, 03, 08, 15, 30, 10); // Get the first date epoch object
// document.write((first.getTime())/1000); // get the actual epoch values
second = new Date(2012, 03, 08, 15, 30, 10); // Get the first date epoch object
//document.write((second.getTime())/1000); // get the actual epoch values
diff= second - first ;
one_day_epoch = 24*60*60 ; // calculating one epoch
if ( diff/ one_day_epoch > 365 ) // check , is it exceei
{
alert( 'date is exceeding one year');
}

date difference and match with value in javascript

Hi I have the Drop down with values as "One year ", "Two year",...etc.. Ok? also i have two ajax textbox with calender extender . I want to popup alert message if dropdown selected value is "One year" and duration between the both textbox value Means dates not matches. getting what i mean ? please help me.
How can i get this scenario in javascript ??
Algorithm :
1.Get the both date from the text box.
2. The find the epcoch time for each date. //
3. subtract the both dates.
4. subtract_result = 365*24*60*60 // Finding the 1 year timestamp values
5. So, it the difference exceed than above calculation , you could sure that the date is mis matching.
Javascript:
// This is for first date
first = new Date(2010, 03, 08, 15, 30, 10); // Get the first date epoch object
document.write((first.getTime())/1000); // get the actual epoch values
second = new Date(2012, 03, 08, 15, 30, 10); // Get the first date epoch object
document.write((second.getTime())/1000); // get the actual epoch values
diff= second - first ;
one_day_epoch = 24*60*60 ; // calculating one epoch
if ( diff/ one_day_epoch > 365 ) // check , is it exceei
{
alert( 'date is exceeding one year');
}