|
80 | 80 | import java.sql.ResultSet; |
81 | 81 | import java.sql.SQLException; |
82 | 82 | import java.sql.Statement; |
| 83 | +import java.sql.Timestamp; |
83 | 84 | import java.sql.Types; |
84 | 85 | import java.time.Duration; |
85 | | -import java.time.LocalDateTime; |
| 86 | +import java.time.Instant; |
86 | 87 | import java.util.ArrayList; |
87 | 88 | import java.util.Arrays; |
88 | 89 | import java.util.Calendar; |
@@ -867,25 +868,25 @@ public SQLFragment getNumericCast(SQLFragment expression) |
867 | 868 | * @param arguments Arguments passed from the LK SQL |
868 | 869 | * @return the dialect equivalent SQLFragrment |
869 | 870 | */ |
870 | | - public SQLFragment getGreatestAndLeastSQL(String method, SQLFragment... arguments) |
871 | | - { |
872 | | - throw new UnsupportedOperationException(getClass().getSimpleName() + " does not implement"); |
873 | | - } |
874 | | - |
875 | | - public boolean supportsIsNumeric() |
876 | | - { |
877 | | - return false; |
878 | | - } |
879 | | - |
880 | | - public SQLFragment isNumericExpr(SQLFragment expression) |
881 | | - { |
882 | | - throw new UnsupportedOperationException(getClass().getSimpleName() + " does not implement"); |
883 | | - } |
884 | | - |
885 | | - public void handleCreateDatabaseException(SQLException e) throws ServletException |
886 | | - { |
887 | | - throw(new ServletException("Can't create database", e)); |
888 | | - } |
| 871 | + public SQLFragment getGreatestAndLeastSQL(String method, SQLFragment... arguments) |
| 872 | + { |
| 873 | + throw new UnsupportedOperationException(getClass().getSimpleName() + " does not implement"); |
| 874 | + } |
| 875 | + |
| 876 | + public boolean supportsIsNumeric() |
| 877 | + { |
| 878 | + return false; |
| 879 | + } |
| 880 | + |
| 881 | + public SQLFragment isNumericExpr(SQLFragment expression) |
| 882 | + { |
| 883 | + throw new UnsupportedOperationException(getClass().getSimpleName() + " does not implement"); |
| 884 | + } |
| 885 | + |
| 886 | + public void handleCreateDatabaseException(SQLException e) throws ServletException |
| 887 | + { |
| 888 | + throw(new ServletException("Can't create database", e)); |
| 889 | + } |
889 | 890 |
|
890 | 891 | /** |
891 | 892 | * Wrap one or more INSERT statements to allow explicit specification |
@@ -2004,13 +2005,14 @@ public void addAdminWarningMessages(Warnings warnings, boolean showAllWarnings) |
2004 | 2005 |
|
2005 | 2006 | public static ServerDatabaseTimeDifference getServerDatabaseTimeDifference(DbScope scope) |
2006 | 2007 | { |
2007 | | - LocalDateTime serverTime = LocalDateTime.now(); |
2008 | | - LocalDateTime databaseTime = new SqlSelector(scope, "SELECT CURRENT_TIMESTAMP").getObject(LocalDateTime.class); |
| 2008 | + // Compare Instants, not wall-clock values, so the skew is measured correctly even when the servers are in different time zones. |
| 2009 | + Instant serverTime = Instant.now(); |
| 2010 | + Instant databaseTime = new SqlSelector(scope, "SELECT CURRENT_TIMESTAMP").getObject(Timestamp.class).toInstant(); |
2009 | 2011 |
|
2010 | 2012 | return new ServerDatabaseTimeDifference(serverTime, databaseTime); |
2011 | 2013 | } |
2012 | 2014 |
|
2013 | | - public record ServerDatabaseTimeDifference(LocalDateTime serverTime, LocalDateTime databaseTime) |
| 2015 | + public record ServerDatabaseTimeDifference(Instant serverTime, Instant databaseTime) |
2014 | 2016 | { |
2015 | 2017 | public long getSeconds() |
2016 | 2018 | { |
@@ -2476,7 +2478,7 @@ public void testProcedureIdentifierQuoting() |
2476 | 2478 | @Test |
2477 | 2479 | public void testServerDatabaseTimeDifference() |
2478 | 2480 | { |
2479 | | - LocalDateTime base = LocalDateTime.of(2026, 7, 6, 12, 0, 0); |
| 2481 | + Instant base = Instant.parse("2026-07-06T12:00:00Z"); |
2480 | 2482 |
|
2481 | 2483 | // Identical times: zero difference, no warning |
2482 | 2484 | ServerDatabaseTimeDifference equal = new ServerDatabaseTimeDifference(base, base); |
|
0 commit comments