11/*******************************************************************************
2- * Copyright (c) 2012-2018 Oak Ridge National Laboratory.
2+ * Copyright (c) 2012-2025 Oak Ridge National Laboratory.
33 * All rights reserved. This program and the accompanying materials
44 * are made available under the terms of the Eclipse Public License v1.0
55 * which accompanies this distribution, and is available at
99
1010import java .time .Duration ;
1111import java .time .Instant ;
12+ import java .time .OffsetDateTime ;
1213import java .time .ZoneId ;
1314import java .time .ZonedDateTime ;
14- import java .util .Calendar ;
1515import java .util .concurrent .TimeUnit ;
1616
1717import org .phoebus .util .time .TimestampFormats ;
1818
1919/** Time stamp gymnastics
2020 * @author Kay Kasemir
2121 */
22- @ SuppressWarnings ("nls" )
2322public class TimestampHelper
2423{
2524 /** @param timestamp {@link Instant}, may be <code>null</code>
@@ -32,17 +31,6 @@ public static String format(final Instant timestamp)
3231 return TimestampFormats .FULL_FORMAT .format (timestamp );
3332 }
3433
35- // May look like just time_format.format(Instant) works,
36- // but results in runtime error " java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra"
37- // because time for printing needs to be in local time
38- // public static void main(String[] args)
39- // {
40- // final Instant now = Instant.now();
41- // System.out.println(format(now));
42- // System.out.println(time_format.format(now));
43- // }
44-
45-
4634 /** @param timestamp EPICS Timestamp
4735 * @return SQL Timestamp
4836 */
@@ -77,14 +65,29 @@ public static Instant fromMillisecs(final long millisecs)
7765 }
7866 return Instant .ofEpochSecond (seconds , nanoseconds );
7967 }
80-
81- /** @param calendar Calendar
82- * @return EPICS Timestamp
68+
69+ /** Zone ID is something like "America/New_York".
70+ * Within that zone, time might change between
71+ * EDT (daylight saving) and EST (standard),
72+ * but the Zone ID remains, so we can keep it final.
8373 */
84- public static Instant fromCalendar (final Calendar calendar )
85- {
86- return fromMillisecs (calendar .getTimeInMillis ());
87- }
74+ final private static ZoneId zone = ZoneId .systemDefault ();
75+
76+ /** Turn SQL {@link java.sql.Timestamp} into {@link OffsetDateTime}
77+ *
78+ * Oracle JDBC PreparedStatement.setTimestamp(int, Timestamp)
79+ * will change the zone info in unexpected ways.
80+ * Using PreparedStatement.setObject(int, OffsetDateTime)
81+ * is the suggested workaround, so this morphs a Timestamp
82+ * into OffsetDateTime
83+ *
84+ * @param sql_time SQL {@link java.sql.Timestamp}
85+ * @return {@link OffsetDateTime}
86+ */
87+ public static OffsetDateTime toOffsetDateTime (final java .sql .Timestamp sql_time )
88+ {
89+ return OffsetDateTime .ofInstant (sql_time .toInstant (), zone );
90+ }
8891
8992 /** Round time to next multiple of given duration
9093 * @param time Original time stamp
0 commit comments