Difference between using `Period.Between` and substracting two local dates - nodatime

Why is the result for the periodBetween.Days and substracted.Days different?
I can see that a periodBetween.Months is 0 and substracted.Months is 2 and I can see how are these two results different, but I don't know why :).
using NodaTime;
void Main()
{
var firstDate = new LocalDate(2020, 8, 1);
var secondDate = new LocalDate(2020, 10, 30);
var periodBetween = Period.Between(firstDate, secondDate, PeriodUnits.Days);
var subtracted = secondDate - firstDate;
Console.WriteLine(periodBetween.Days);
Console.WriteLine(subtracted.Days);
}

Your periodBetween calculation is saying "What's the period between these two dates, using only days?"
Your subtracted calculation is equivalent to calling Period.Between either without specifying any units, or specifying PeriodUnits.Days | PeriodUnits.Months | PeriodUnits.Years - in other words, "What's the period between these two dates, using days, months and years?"
A period has independent values for years, months, days, hours, minutes etc - if you compute a value using years/months/days that's not equivalent to computing a value using just days.
A period of "90 days" is not the same as a period of "2 months and 29 days". In some calculations they'll give the same answer, but not always. For example, if you add "90 days" to January 1st 2020, you'll get March 31st 2020... but if you add "2 months and 29 days" to January 1st 2020, you'll get March 30th 2020.

Related

Limit max day of Data for all months

I need to calculate, over months, the value of Sales in every month limiting the max day of my data = my Day(DateTimeNow()) - 1.
Examples:
Today is 25 of march, i wanna see in my bar chart the total of Sales until day 24 for january, february and march.
Today is 02 of april, my bar chart will show the sales of day 1 for january, february, march and april.
I've tried using limit data in my graph like so I set the max day of my Date to be the Day(DateTimeNow()) - 1
Max(Day([DATE])) = Day(DateTimeNow()) - 1
That way I set the max Day for my date to be equal my Day - 1
I've tried using ParallelPeriod too.
I expect that using:
Max(Day([DATE])) = Day(DateTimeNow()) - 1
I've got like:
Max(Day([DATE])) = 31
Day(DateTimeNow()) - 1 = 02
( Max(Day([DATE])) = Day(DateTimeNow()) - 1 )
I know that this results in a boolean expression, so:
31 = 02 -> False
But i just want to set the Max Day to be 02.
This expression below should fit your needs. Put this expression in the Limit data using expression of the visualization options.
Day([DATE])<Day(DateTimeNow())-1
It takes, for each months, the days before current day - 1. If we are on the first of the month, then no data will be available.

US convention different in spreadsheet functions (Libre, Google Sheets, etc.)

The Excel/Google-Sheets/LibreOffice function DAYS360() returns the number of days between two dates based on a 360-day year. 0 (default) is used for the US-based method and here are some examples
A = 30 Apr 2016, B = 29 Feb 2016, DAYS360(A, B) = -61
A = 29 Feb 2016, B = 30 Apr 2016, DAYS360(A, B) = 60
This seems ok according to the rules here
But the Excel/Google-Sheets/LibreOffice function YEARFRAC() returns the number of years, including fractional years, between two dates using a specified day count convention. Even here 0 (default) uses US method, (US (NASD) 30/360) which I presumed will also be equal to the value of number of days calculated by DAYS360 * the number of seconds in a day/number of seconds in 360 days. The values in the sheets are as follows
A = 30 Apr 2016, B = 29 Feb 2016, YEARFRAC(A, B) = 0.1666666667
A = 29 Feb 2016, B = 30 Apr 2016, YEARFRAC(A, B) = 0.1666666667
Since it can be seen that the absolute value of the DAYS360 is different by one, the YEARFRAC value is same and assumes 60 days according to the presumption made above, so are the US-based convention mentioned here is the same as mentioned for DAYS360.
If not, what are the exact rules for this one, or is there some other problem?
NOTE: Tested these values on Google Sheets and Libre Office.
DAYS360 parameter 3:
0 indicates the US method - Under the US method, if start_date is the last day of a month, the day of month of start_date is changed to
30 for the purposes of the calculation. Furthermore if end_date is the
last day of a month and the day of the month of start_date is earlier
than the 30th, end_date is changed to the first day of the month
following end_date, otherwise the day of month of end_date is changed
to 30.
1 or any other value indicates the European method - Under the European method, any start_date or end_date that falls on the 31st of
a month has its day of month changed to 30.
YEARFRAC parameter 3:
0 indicates US (NASD) 30/360 - This assumes 30 day months and 360 day
years as per the National Association of Securities Dealers standard,
and performs specific adjustments to entered dates which fall at the
end of months.
1 indicates Actual/Actual - This calculates based upon the actual
number of days between the specified dates, and the actual number of
days in the intervening years. Used for US Treasury Bonds and Bills,
but also the most relevant for non-financial use.
2 indicates Actual/360 - This calculates based on the actual number of
days between the specified dates, but assumes a 360 day year.
3 indicates Actual/365 - This calculates based on the actual number of
days between the specified dates, but assumes a 365 day year.
4 indicates European 30/360 - Similar to 0, this calculates based on a
30 day month and 360 day year, but adjusts end-of-month dates
according to European financial conventions.

Numerical month to character month in excel

Is there a pre-installed function that directly converts 08 to Aug, 10 to Oct?
Currently I use text(date(0,have,1),"mmm").
You could simplify like this: =TEXT("8/0","mmm").
Update
I've come up with a new technique: =TEXT(number * 30,"mmm"):
How it works
Dates are stored as numbers in Excel. The number 1 is the date Jan 1, 1900; 2 is Jan 2, 1900; etc.
The 30th day in 1900 is in January; the 60th day is in February; the 90th day is in March.
Every multiple of 30 between 30 and 360 is in a different month. So we can simply multiply 30 by a number between 1 and 12, and the TEXT function will give us the month.
You can use
MonthName(yourmonthNumber)
or
MonthName(yourmonthNumber, True) 'to abbreviate the name
Or did you mean a worksheet function?

how to calculate the number of the week in a year?

I would like to calculte the number of the week in a year. I see this post
In this post the acepted answer use this code:
public static int GetIso8601WeekOfYear(DateTime time)
{
// Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll
// be the same week# as whatever Thursday, Friday or Saturday are,
// and we always get those right
DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
// Return the week of our adjusted day
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
However I see a problem. The number of the week is repeated if the last day of a month is in Sunday.
For example, the last day of March of 2013 year is in sunday. This week is the number 13th, is correct. But in April, how C# use always 6 weeks in a month to calculate the number of week, the first week of april has not any day of april, because all the days belong to march because the last day of the week is 30th March. So C# says that the first week of april is th 15th week, but this is incorrect, it has to be 14th.
So I would like to know if there are any way to calculate the number of a week in a right way.
EDIT:
I mean this:
In march, the last week is this:
25 26 27 28 29 30 31
This is the 13th, is correct.
In april, the first week is:
1 2 3 4 5 6 7
And this week is calculated as 15th.
So if I see the march calendar the last week is calculated as 13th and if I see the april calendar the last week of march is caluclated as 14th. This is incorrect.
SOLUTION:
DateTime dtCalendar = Calendar.DisplayDate;
int gridRow = (int)GetValue(Grid.RowProperty);
// Return the week of our adjusted day
int wueekNumber= System.Globalization.CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dtCalendar, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday);
if (dtCalendar.DayOfWeek == DayOfWeek.Monday)
{
gridRow = gridRow - 1;
}
Text = (weekNumbe r+ gridRow - 1).ToString();
Thanks.
The problem is that you are using the wrong CalendarWeekRule. To get the result you want you should use FirstDay. I have seen various codes in internet saying that you should use FirstFourDayWeek but, after some testing, I realised that the "right one" is FirstDay. I have tested it with your example and it delivers the right result: 14th week.
int targetYear = 2013;
DateTime targetDate = new DateTime(targetYear, 4, 1);
int week = System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(targetDate, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday);

Using Workday when start date is a wekeend date

I have a spreadhseet that pulls Planned Maintenace due dates. I am calculating 5 potential days the work can be scheduled, from 2 days before to days days after, so a range of 5 days. Unfortunately, sometimes the original due date is a weekend date(our business system calculates but doesn't append for weekend dates). So when I calculate the first 2 days, =workdate(A1,-2,holiday) and =workdate(A1,-1,holiday)it works fine, however for the 3rd date =workdate(A1,0,holiday) returns the original due date even if it's a weekend date.
Example, July 6th 2013 is a Saturday, so
1. workdate(A1,-2,holiday) = 7/3/2013
2. workdate(A1,-1,holiday) = 7/5/2013
3. workdate(A1,0,holiday) = 7/6/2013 needs to be 7/8/2013
4. workdate(A1,1,holiday) = 7/8/2013 needs to be 7/9/2013
5. workdate(A1,2,holiday) = 7/9/2013 needs to be 7/10/2013
Is there any way to compensate for a start date that is a weekend date!
Thanks in advance for any help or suggestions.
The function it appears you are using is workday(), not workdate()? So what you probably need to do is put an adjustment on the # you pass to Workday if the day of the week is Sat/Sun.
=WORKDAY(A1,IF(OR(TEXT(A1,"ddd") = "Sat",TEXT(A1,"ddd") = "Sun"),1,0))
=WORKDAY(A1,IF(OR(TEXT(A1,"ddd") = "Sat",TEXT(A1,"ddd") = "Sun"),2,1))
=WORKDAY(A1,IF(OR(TEXT(A1,"ddd") = "Sat",TEXT(A1,"ddd") = "Sun"),3,2))

Resources