Search code examples
datedatetimesalesforceapexdata-conversion

Converting the Time format in dateTime from 00:00:00 to 23:59:59


I have converted a Date into DateTime format, and it is returning me the hour format in 00:00:00 but I want it to be in 23:59:59

Date startDate = Date.newInstance(2021,2,1);

This returns the output as 2021-02-01 00:00:00

When I try to convert this to the 23:59:59 hour format by using the below code

DateTime startDateConvertTwo = DateTime.newInstance(startDate, Time.newInstance(23, 59, 59, 0));

It is pushing the date to next day and returning the value of 2021-02-02 07:59:59

I tried to sort this out by changing the values of Time.newInstance by adding it as Time.newInstance(15, 59, 59, 0) by doing which I get the expected result. But is it the right way to achieve what I am trying to do?

Please let me know if there are any other ways.


Solution

  • The returned output of Date startDate = Date.newInstance(2021,2,1); is not 2021-02-01 00:00:00. It's just a date with no information about time, but System.debug() display it as a DateTime, that's why you see 00:00:00.
    Try System.debug(String.valueOf(startDate)); to see only the Date part.


    DateTime.newInstance(date, time)

    Constructs a DateTime from the specified date and time in the local time zone.

    As documentation states, the DateTime you get is in your own time zone. Anyway System.debug() shows it in UTC time zone (GMT+0), so if your time zone is GMT-8 you'll see 2021-02-02 07:59:59.
    System.debug(String.valueOf(startDateConvertTwo )); will shows the DateTime in your own time zone, so you'll see 2021-02-01 23:59:59.

    If you need a DateTime in GMT you could use DateTime.newInstanceGmt(date, time):

    DateTime startDateGMT = DateTime.newInstanceGmt(startDate, Time.newInstance(23, 59, 59, 0));
    

    If you cannot use that method, you could add your offset to a DateTime:

    public static DateTime toUTC(DateTime value) {
        Integer offset = UserInfo.getTimezone().getOffset(value);
        return value.addSeconds(offset/1000);
    }
    

    You could test it in anonymous console:

    Date startDate = Date.newInstance(2021,2,1);
    DateTime startDateConvertTwo = DateTime.newInstance(startDate, Time.newInstance(23, 59, 59, 0));
    DateTime startDateGMT = DateTime.newInstanceGmt(startDate, Time.newInstance(23, 59, 59, 0));
    DateTime startDateGMT2 = toUTC(startDateConvertTwo);
    
    System.debug('startDateConvertTwo: ' + startDateConvertTwo); // startDateConvertTwo: 2021-02-01 22:59:59 // Because I'm at GMT+1
    System.debug('String.valueOf(startDateConvertTwo): ' + String.valueOf(startDateConvertTwo));  // String.valueOf(startDateConvertTwo): 2021-02-01 23:59:59
    
    System.debug('startDateGMT: ' + startDateGMT); // startDateGMT: 2021-02-01 23:59:59 // Now it's in UTC
    System.debug('String.valueOf(startDateGMT): ' + String.valueOf(startDateGMT)); // String.valueOf(startDateGMT): 2021-02-02 00:59:59 // So in my locale time it's the day after,
    
    System.debug('startDateGMT2: ' + startDateGMT2); // startDateGMT2: 2021-02-01 23:59:59 // Same as startDateGMT
    System.debug('String.valueOf(startDateGMT2): ' + String.valueOf(startDateGMT2)); // String.valueOf(startDateGMT2): 2021-02-02 00:59:59
    
    public static DateTime toUTC(DateTime value) {
        Integer offset = UserInfo.getTimezone().getOffset(value);
        return value.addSeconds(offset/1000);
    }
    

    The output of startDateGMT and startDateGMT2 will be the same.

    Noteworthy: DateTime fields are stored in GMT. When shown in the standard Salesforce UI, they're converted to the user's timezone.