Skip to content

Standard Offset and Daylight Savings #557

@Otsoko

Description

@Otsoko

Hello to everyone reaching this issue.

It seems that the kotlinx-datetime library is not delegating to the ZoneRules.getStandardOffset(), and the ZoneRules.getDaylightSavings() and ZoneRules.isDaylightSavings() to the java.time API, but it is delegating to the ZoneRules.getOffset() using TimeZone.offsetAt(Instant).

I have already checked the closed issues #296 and #396, which seem to ask for similar functionalities, but they could not present a valid use case, so here we go.

When communicating with a Bluetooth Low Energy (BLE) device that implements the BLE specification, the datetimes are specified by the Time Zone and DST Offset characteristics separately. You can find the definition of those characteristics in the GATT Specification Supplement (PDF) on pages 178 and 85, respectively. Note that the Time Zone characteristic definition says: The offset defined in this characteristic is constant regardless of whether daylight savings is in effect.

An example using the java.time API is as follows:

// Time Zone offset
val offset = ZoneId.systemDefault().rules.getStandardOffset(dateTime.toInstant())
val fifteenMinuteIncrements = offset.totalSeconds / 60 / 15
buffer.writeByte(fifteenMinuteIncrements.toByte()) // UTC+1 (4*15)

// Daylight savings DST offset
val isDst = ZoneId.systemDefault().rules.isDaylightSavings(dateTime.toInstant())
if (isDst.not()) {
    buffer.writeByte(0x00) // Standard time
} else {
    val dstOffset = ZoneId.systemDefault().rules.getDaylightSavings(dateTime.toInstant())
    when (dstOffset.toMinutes().toInt()) {
        30 -> buffer.writeByte(0x02)  // DST +0.5h
        60 -> buffer.writeByte(0x04)  // DST +1h
        120 -> buffer.writeByte(0x08) // DST +2h
        else -> buffer.writeByte(0xFF.toByte()) // DST offset unknown
    }
}

where buffer.writeByte() is used to write that byte into a buffer (from Kotlinx-io library) to be sent via BLE.

As far as I know, this can't be achieved with kotlinx-datetime, since the code

val currentTimeZone = TimeZone.currentSystemDefault()
val utcOffset = currentTimeZone.offsetAt(dateTime.toInstant(currentTimeZone))

obtains the whole offset from UTC (Time Zone standard offset + DST offset).

Of course, we can use the java.time API, but that would break the whole KMP idea and the goal of kotlinx-datetime.

Is there a chance to add these functions to the library, with that use case in mind?

Thanks for your attention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions