Skip to content

Commit

Permalink
Allow constructing a microsoft.sql.DateTimeOffset instance from a jav…
Browse files Browse the repository at this point in the history
…a.time.OffsetDateTime value
  • Loading branch information
arashi01 committed Feb 27, 2024
1 parent cfb018a commit ae407c4
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/main/java/microsoft/sql/DateTimeOffset.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ private DateTimeOffset(java.sql.Timestamp timestamp, int minutesOffset) {
assert 0 == this.utcMillis % 1000L : "utcMillis: " + this.utcMillis;
}

/**
* Constructs a DateTimeOffset from an existing java.time.OffsetDateTime
*
* @param offsetDateTime A java.time.OffsetDateTime value
* @apiNote DateTimeOffset represents values to 100ns precision. If the java.time.OffsetDateTime instance represents
* a value that is more precise, values in excess of the 100ns precision are rounded to the nearest
* multiple of 100ns. Values within 50 nanoseconds of the next second are rounded up to the next second.
*/
private DateTimeOffset(java.time.OffsetDateTime offsetDateTime) {
int hundredNanos = ((offsetDateTime.getNano() + 50) / 100);
this.utcMillis = (offsetDateTime.toEpochSecond() * 1000) + (hundredNanos / HUNDRED_NANOS_PER_SECOND * 1000);
this.nanos = 100 * (hundredNanos % HUNDRED_NANOS_PER_SECOND);
this.minutesOffset = offsetDateTime.getOffset().getTotalSeconds() / 60;
}

/**
* Converts a java.sql.Timestamp value with an integer offset to the equivalent DateTimeOffset value
*
Expand Down Expand Up @@ -105,6 +120,19 @@ public static DateTimeOffset valueOf(java.sql.Timestamp timestamp, Calendar cale
(calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000));
}

/**
* Directly converts a {@link java.time.OffsetDateTime} value to an equivalent {@link DateTimeOffset} value
*
* @param offsetDateTime A java.time.OffsetDateTime value
* @return The DateTimeOffset value of the input java.time.OffsetDateTime
* @apiNote DateTimeOffset represents values to 100ns precision. If the java.time.OffsetDateTime instance represents
* a value that is more precise, values in excess of the 100ns precision are rounded to the nearest
* multiple of 100ns. Values within 50 nanoseconds of the next second are rounded up to the next second.
*/
public static DateTimeOffset valueOf(java.time.OffsetDateTime offsetDateTime) {
return new DateTimeOffset(offsetDateTime);
}

/** formatted value */
private String formattedValue = null;

Expand Down
54 changes: 54 additions & 0 deletions src/test/java/microsoft/sql/DateTimeOffsetTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
* available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/

package microsoft.sql;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class DateTimeOffsetTest {

@Test
@DisplayName("DateTimeOffset.valueOf(offsetDateTime) instantiates correct DateTimeOffset instances.")
void valueOfOffsetDateTime() {
int nanos = 123456789;
int hundredNanos = 1234568; // DateTimeOffset has a precision of 100 nanos of second
OffsetDateTime offsetDateTime = OffsetDateTime.of(
2024,
2,
25,
23,
55,
6,
nanos,
ZoneOffset.ofHoursMinutes(1, 30)
);
Assertions
.assertEquals(
offsetDateTime.withNano(hundredNanos * 100),
DateTimeOffset.valueOf(offsetDateTime).getOffsetDateTime()
);
}

@Test
@DisplayName("DateTimeOffset.valueOf(offsetDateTime) correctly rounds up values within 50 nanoseconds of the next second.")
void valueOfOffsetDateTimeRounding() {
OffsetDateTime offsetDateTime =
OffsetDateTime.now()
.withSecond(58)
.withNano(999999950);
Assertions
.assertEquals(
offsetDateTime
.withSecond(59)
.withNano(0),
DateTimeOffset.valueOf(offsetDateTime).getOffsetDateTime()
);
}
}

0 comments on commit ae407c4

Please sign in to comment.