locked
Whats a stable type-safe way to subtract 6 Months from any date? RRS feed

  • Question

  • User2142845853 posted
    val x = DateTime.Now - TimeSpan.FromDays(1);
    
    DateTime dt1, dt2 = new DateTime();
    
    dt1 = DateTime.Now 
    dt2 = dt1.AddMonths(-6);
    
     

    Here are 2 different ways to subtract time from a DateTime variable, but 365 days a year, so subtract (365/2) ?

    Result of dt2 = dt1.AddMonths(-6);

    if dt1 = 12/1/2019 then dt2 = 7/1/1899  

    but 8/1/2019 gets 2/1/2019.  Is there a safe certain way without writing a custom method?

    Tuesday, September 10, 2019 5:02 AM

Answers

  • User2142845853 posted

    such a WASTE OF TIME.

    var1

    var2

    var3

    var4

    var8

    var9

    var1   <----- should be var10

    So when copying vertical sets of values using ALT i had missed a zero and didnt realize.  it got to the 10th item which was not used and zapped var1 which is used. Looked at that code a zillion times.  All it took to waste a bunch of hours.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 10, 2019 10:47 PM

All replies

  • User-821857111 posted

    DateTime.AddMonths is the proper way to add or subtract months to a date. If dt1 = new Datetime(2019,12,1), then dt2 = 2019-6-1. There are indeed 365 days in a year, but that has nothing to do with months. If you want to subtract a given number of days, use Datetime.AddDays,

    Maybe you should define what you mean by "months" first. 

    Tuesday, September 10, 2019 6:37 AM
  • User2142845853 posted

    DateTime.AddMonths is the proper way to add or subtract months to a date. If dt1 = new Datetime(2019,12,1), then dt2 = 2019-6-1. There are indeed 365 days in a year, but that has nothing to do with months. If you want to subtract a given number of days, use Datetime.AddDays,

    Maybe you should define what you mean by "months" first. 

    Im calculating Fiscal Years for a reporting app.  The software exists and works fine. The problem is that I used the calendar date not FY date, so January 2019 is the 3rd qtr of 2018. IOW my program takes in January 1, 2019 where it must take in July 1, 2018 as the right date 

    January 2019 (actual) = July 2018 (Fiscal) or Fiscal = actual - 6 months

    So trying to subtract 6 months, what happens if its month 5, take away 6? or leap year?  

    Tuesday, September 10, 2019 3:00 PM
  • User-821857111 posted

    The documentation explains the algorithm that AddMonths employs: https://docs.microsoft.com/en-us/dotnet/api/system.datetime.addmonths?view=netframework-4.8

    If you call AddMonths(-6) on a date in May (month 5) 2019, you get a date in the preceding November (month 11, 2018). e.g

    Console.WriteLine(new DateTime(2019,5,2).AddMonths(-6));

    will result in 

    02/11/2018 00:00:00 (in my locale - UK)

    Tuesday, September 10, 2019 4:02 PM
  • User2142845853 posted

    ok hold on--may have found the problem. not all date values are used.  will try something and see

    Yes, I was getting that on most of the DateTime vars. but on 3 out of 15 it was returning 1899 as the year.   You can see the starting var with a date in 2019, and I did a multiple paste with alt/select so all vars are lined up nicely. In debug the value of the date is like BVariable = (AVariable).AddMonths(-6)  but the resulting year is 1899.  You can hover over AVariable and it shows a normal date like "4/1/2019"

    Tuesday, September 10, 2019 5:50 PM
  • User753101303 posted

    Hi

    "if dt1 = 12/1/2019 then dt2 = 7/1/1899" By adding -6 months. You likely have some kind bug in your code. Could you show us the simplest code giving this Strange result.

      class Program
        {
            static void  Main(string[] args)
            {
    
                var dt1 = new DateTime(2019, 12, 1);
                var dt2 = dt1.AddMonths(-6);
                Console.WriteLine(dt2==new DateTime(2019,6,1)); // Shows true
            }
        }

    Edit: ah more likely you ended up in saving an empty string to the db which default to 01/01/1900 in SQL Server. And so if you later subtract 6 month you end up with your 07/01/1899 result :

    SELECT DATEADD(month,-6,'') -- shows 1899-07-01

    IMO this is actually caused by something wrong when inserting values in your db...

    Tuesday, September 10, 2019 6:12 PM
  • User2142845853 posted

    Create the  variables then fill from the sql database.  values are there or theyre not.  

    so its as simple as what I posted, the variable has the live data value or not.  If there are a list of 1 thru 15 for a set of dates, only 1 or 1 and 2 or 1 and 2 and 3 etc will have data, at no time can it have no data in 1 but data in 2 -7.  so I pick 1 because it caused an error in the app, the value its converting is "4/1/2019" and the converted value's year is 1899 unless the debugger...   maybe the value being converted is added/changed after its already created the 1899 year

    but I think its what youre saying 1/1/1900 as a default date.  this was all working fine and using the same file for weeks so I know which ones have useful values now the first one in a set comes back 1899, maybe something got changed further up the chain.

    thanks

    Tuesday, September 10, 2019 6:46 PM
  • User2142845853 posted

    such a WASTE OF TIME.

    var1

    var2

    var3

    var4

    var8

    var9

    var1   <----- should be var10

    So when copying vertical sets of values using ALT i had missed a zero and didnt realize.  it got to the 10th item which was not used and zapped var1 which is used. Looked at that code a zillion times.  All it took to waste a bunch of hours.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 10, 2019 10:47 PM
  • User303363814 posted

    You need to think about what you are trying to do

    What is one month before March 30th? (March 30 is the second last day of the month. the 30th day after the start of the month,  it is also the fifth Saturday of the month this year as well as the last Saturday, the Saturday after the fourth Monday, etc, etc)

    A) Feb 27 because it is the second last day of the previous month

    B) Feb 28 because there is no Feb 30 and so you stop counting

    C) Mar 2, because it is 30 days after the start of the previous month

    D) Feb 23, because that is the last Saturday of February

    If you think option A is correct then what about Mar 20?  Does that become Feb 17 because it is also 11 days before the end of the month

    If you think Option B is correct then what would one month after Feb 28 be?  March 28?  IF so then subtract one month and then adding one month does not get you back to the starting date.

    Using DateTime.AddMonths will provide an answer to these questions - but is it the answer you want?

    The most important aspect of code is that it is correct and does what you require!  If you don't know what you require then it is very difficult to be correct.

    (Bottom line - months suck because everybody has a different opinion of what one is!)

    Tuesday, September 10, 2019 10:57 PM
  • User2142845853 posted

    Not sure why any confusion, look at the calendar ok? its got months on there, right? you see the names of each month? we were taught the names sound like: January, February, March and so on... and the last one? is December.  You see a bunch of numbers under each month, they seem to start with "1" and increment +1 for each day that takes place.  Some months have 31 days, like the saying goes 31 days has September, April May and November.  And it seems like the pattern repeats every 7 or so years.

    So the calendar is what we reference.  if this is 2019? Then a calendar exists that reflects all the "months".  If you say June 7th? chances are you can find that on a calendar and figure out how many days to this or that month.

    Fiscal years are different. The year may start in April or June or July.  So the date August 13, 2019, which Quarter is it in?  Calendar qtr its 3.  if the fiscal year starts in April then its some other number.

     I took dates as literal, but  If I was designing the fiscal year from the start I would have used the switch case to say 

    switch(month)

    case: 1

    case: 2

    case: 3

    ThisQuarter = 3;

    break;

    case 4:

    case 5:

    case 6:

    ThisQuarter = 4;

    break;

    So now the solution can be had by carefully setting the Fiscal year and quarter. The problem happened because of the copy/paste of vertical columns, late at night. 

    it works right now, it just seemed like an impossible value was happening for variable 1.  missing the 0 for variable10?  it got re written with junk

    Tuesday, September 10, 2019 11:49 PM