system.date.getDayOfMonth unexpected output

I'm trying to check if a date is exactly one year apart, to the second - I wanted to include leap years, so I consulted the docs and found this:

However, I tried selecting the same exact date from a date picker but one in 2024 and one in 2025, and I would get a value of > 0. So I decided to check each part of the date so that I can capture the case where the dates are exactly one year apart, to the second.

Here is what that looks like in the script console (don't judge):

the code
startDate = system.date.parse('2024-01-01 00:00:00', 'YYYY-MM-dd HH:mm:ss')
endDate = system.date.parse('2025-01-01 00:00:00', 'YYYY-MM-dd HH:mm:ss')

print system.date.yearsBetween(startDate, endDate)
print system.date.getSecond(startDate) == system.date.getSecond(endDate)
print system.date.getMinute(startDate) == system.date.getMinute(endDate)
print system.date.getHour24(startDate) == system.date.getHour24(endDate)
print 'about to print dayOfMonth...'
print system.date.getDayOfMonth(startDate) 
print system.date.getDayOfMonth(endDate)
print 'just printed dayOfMonth'
print system.date.getMonth(startDate) == system.date.getMonth(endDate)
print system.date.yearsBetween(startDate, endDate) == 0

Why do I get unexpected results for getDayOfMonth, when they both should be 1 - at least that's what it looks like it should be on the surface. If that's the expected behavior, why?

Time to play 'spot the difference':

startDate = system.date.parse('2024-01-01 00:00:00', 'yyyy-MM-dd HH:mm:ss')
endDate = system.date.parse('2025-01-01 00:00:00', 'yyyy-MM-dd HH:mm:ss')

print system.date.yearsBetween(startDate, endDate)
print system.date.getSecond(startDate) == system.date.getSecond(endDate)
print system.date.getMinute(startDate) == system.date.getMinute(endDate)
print system.date.getHour24(startDate) == system.date.getHour24(endDate)
print 'about to print dayOfMonth...'
print system.date.getDayOfMonth(startDate) 
print system.date.getDayOfMonth(endDate)
print 'just printed dayOfMonth'
print system.date.getMonth(startDate) == system.date.getMonth(endDate)
print system.date.yearsBetween(startDate, endDate) == 0

YYYY in system.date.parse gives you the 'ISO week year', not the expected calendar year - yyyy is what you actually want.

3 Likes

I was just about to comment that the format string was breaking this...

startDate = system.date.parse('2024-01-01 00:00:00')
endDate = system.date.parse('2025-01-01 00:00:00')

print system.date.yearsBetween(startDate, endDate)
print system.date.getSecond(startDate) == system.date.getSecond(endDate)
print system.date.getMinute(startDate) == system.date.getMinute(endDate)
print system.date.getHour24(startDate) == system.date.getHour24(endDate)
print 'about to print dayOfMonth...'
print startDate
print endDate
print system.date.getDayOfMonth(startDate) 
print system.date.getDayOfMonth(endDate)
print 'just printed dayOfMonth'
print system.date.getMonth(startDate) == system.date.getMonth(endDate)
print system.date.yearsBetween(startDate, endDate) == 0
1 Like

I can't believe I missed something so silly :frowning: Thank you for the quick response!

The reason I was testing that monstrosity was because I'm trying to limit a user to only 1 year's worth of data BUT when I select Feb 1, 2024 12:00 AM and Feb 1, 2025 12:00 AM, I get system.date.yearsBetween() = 1, which is okay, but then I don't know if its exactly one year to the second, or 1 year 11 months, etc.

What would be the best way to check if two dates are at most exactly one year apart, taking into account leap years?

:grimacing:

Datetime math is complicated.

ChatGPT suggested something like this, after some prodding:

def isAtMostOneYearApart(date1, date2):
    # Ensure date1 is the earlier date
    if date1.after(date2):
        date1, date2 = date2, date1

    # Get the number of whole years apart
    years_diff = system.date.yearsBetween(date1, date2)

    # If within the same year, return True
    if years_diff == 0:
        return True

    # If exactly one year apart, check if the days difference is within a year span
    if years_diff == 1:
        return system.date.daysBetween(date1, date2) <= 366  # Account for leap years

    return False

The general approach I think makes sense - first, check if they're within a year - easy. If they're a year apart, check if adding a year's worth of days to one gives you the same date as the other.

There's possibly a more elegant way to do this with the java.time API, but we don't have any nice helpers for that library, so it would end up pretty awkward to use.

1 Like

Given t0 and t1:
Use t1x = system.date.addYears(t0, 1) with the earlier endpoint. Check t1.time == t1x.time.

That will check for exactly a year apart, to the millisecond. Use integer divide by 1000 to ignore millis.

.addYears() handles leap years.

2 Likes