[SalesForce] DateTime.addMonths skips a month (from feb to mar)

I'm writing some code to get each months name between a start and an end date. This works fine for most months – except February into march, and november – december.

Heres the code :

Date startDate = Date.parse('5/30/2019');
Date endDate = startDate.addYears(1);

Integer durationInMonths = StartDate.MonthsBetween(EndDate);

for (Integer i = 0; i <= durationInMonths; i++) {
    DateTime m = DateTime.newInstance( StartDate.Year(), StartDate.Month(), 1);

    m = m.addMonths(i); 

    System.debug(i);
    System.debug(m.Day() + ' / ' + m.Month() + ' / ' + String.valueOf(m.year()));                
}

Here you can see the crazy output (DD/MM/YY) – at one point (1/11/19 -> 30/11/19) the date picks up some days instead of months and then the whole thing falls apart. The scary part is that I didn't notice until now due to the output being put into a set and only using (MM/YY).

enter image description here

Best Answer

Not an answer, but a clue, it seems it has to do something related to timezone and summer time. Same code in my BST org gives a different response.

Date startDate = Date.parse('30/05/2019');
Date endDate = startDate.addYears(1);

Integer durationInMonths = StartDate.MonthsBetween(EndDate);

for (Integer i = 0; i <= durationInMonths; i++) {
    DateTime m = DateTime.newInstance( StartDate.Year(), StartDate.Month(), 1);

    m = m.addMonths(i);

    System.debug(i);
    System.debug(m.Day() + ' / ' + m.Month() + ' / ' + String.valueOf(m.year()));
}

Debug :

17:17:14.14 (16267512)|USER_DEBUG|[11]|DEBUG|0
17:17:14.14 (16351252)|USER_DEBUG|[12]|DEBUG|1 / 5 / 2019
17:17:14.14 (16404681)|USER_DEBUG|[11]|DEBUG|1
17:17:14.14 (16434289)|USER_DEBUG|[12]|DEBUG|31 / 5 / 2019
17:17:14.14 (16453217)|USER_DEBUG|[11]|DEBUG|2
17:17:14.14 (16480510)|USER_DEBUG|[12]|DEBUG|1 / 7 / 2019
17:17:14.14 (16498216)|USER_DEBUG|[11]|DEBUG|3
17:17:14.14 (16524565)|USER_DEBUG|[12]|DEBUG|31 / 7 / 2019
17:17:14.14 (16542405)|USER_DEBUG|[11]|DEBUG|4
17:17:14.14 (16568781)|USER_DEBUG|[12]|DEBUG|31 / 8 / 2019
17:17:14.14 (16592710)|USER_DEBUG|[11]|DEBUG|5
17:17:14.14 (16619134)|USER_DEBUG|[12]|DEBUG|1 / 10 / 2019
17:17:14.14 (16636368)|USER_DEBUG|[11]|DEBUG|6
17:17:14.14 (16663050)|USER_DEBUG|[12]|DEBUG|30 / 10 / 2019
17:17:14.14 (16680525)|USER_DEBUG|[11]|DEBUG|7
17:17:14.14 (16706633)|USER_DEBUG|[12]|DEBUG|30 / 11 / 2019
17:17:14.14 (16723573)|USER_DEBUG|[11]|DEBUG|8
17:17:14.14 (16750065)|USER_DEBUG|[12]|DEBUG|30 / 12 / 2019
17:17:14.14 (16767156)|USER_DEBUG|[11]|DEBUG|9
17:17:14.14 (16793676)|USER_DEBUG|[12]|DEBUG|30 / 1 / 2020
17:17:14.14 (16810795)|USER_DEBUG|[11]|DEBUG|10
17:17:14.14 (16837147)|USER_DEBUG|[12]|DEBUG|29 / 2 / 2020
17:17:14.14 (16854164)|USER_DEBUG|[11]|DEBUG|11
17:17:14.14 (16880438)|USER_DEBUG|[12]|DEBUG|31 / 3 / 2020
17:17:14.14 (16897409)|USER_DEBUG|[11]|DEBUG|12
17:17:14.14 (16923463)|USER_DEBUG|[12]|DEBUG|1 / 5 / 2020

EDIT:

When you do

Date startDate = Date.parse('30/05/2019');

System.debug(startDate); //Prints 2019-05-30 00:00:00

Which is SummerTime/DaylightSaving 1 hour ahead. So Actual DateTime is 2019-05-29 23:00:00

Am not sure if there can be more than 1 hour in DST, so on safe side I have added 2 hours as offset and it gives me correct response.

Datetime startDate = Datetime.newInstance(2019,05,30 , 2, 0, 0);


for(Integer i =0 ;i < 12;i++){
    startDate = startDate.addMonths(1);
    System.debug(startDate);
}

Debug :

17:47:17.14 (15747813)|USER_DEBUG|[6]|DEBUG|2019-06-30 01:00:00
17:47:17.14 (15781585)|USER_DEBUG|[6]|DEBUG|2019-07-30 01:00:00
17:47:17.14 (15793019)|USER_DEBUG|[6]|DEBUG|2019-08-30 01:00:00
17:47:17.14 (15804331)|USER_DEBUG|[6]|DEBUG|2019-09-30 01:00:00
17:47:17.14 (15817668)|USER_DEBUG|[6]|DEBUG|2019-10-30 01:00:00
17:47:17.14 (15827719)|USER_DEBUG|[6]|DEBUG|2019-11-30 01:00:00
17:47:17.14 (15837722)|USER_DEBUG|[6]|DEBUG|2019-12-30 01:00:00
17:47:17.14 (15848084)|USER_DEBUG|[6]|DEBUG|2020-01-30 01:00:00
17:47:17.14 (15862108)|USER_DEBUG|[6]|DEBUG|2020-02-29 01:00:00
17:47:17.14 (15874963)|USER_DEBUG|[6]|DEBUG|2020-03-29 01:00:00
17:47:17.14 (15884811)|USER_DEBUG|[6]|DEBUG|2020-04-29 01:00:00
17:47:17.14 (15894518)|USER_DEBUG|[6]|DEBUG|2020-05-29 01:00:00
Related Topic