You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LocalDateTimeTest.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. Copyright (c) 2018 James Ahlborn
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package com.healthmarketscience.jackcess;
  14. import java.text.DateFormat;
  15. import java.text.SimpleDateFormat;
  16. import java.time.Instant;
  17. import java.time.LocalDate;
  18. import java.time.LocalDateTime;
  19. import java.time.ZoneId;
  20. import java.time.ZonedDateTime;
  21. import java.time.format.DateTimeFormatter;
  22. import java.util.ArrayList;
  23. import java.util.Arrays;
  24. import java.util.Calendar;
  25. import java.util.Date;
  26. import java.util.List;
  27. import java.util.TimeZone;
  28. import com.healthmarketscience.jackcess.impl.ColumnImpl;
  29. import com.healthmarketscience.jackcess.impl.DatabaseImpl;
  30. import junit.framework.TestCase;
  31. import static com.healthmarketscience.jackcess.TestUtil.*;
  32. import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
  33. import static com.healthmarketscience.jackcess.Database.*;
  34. /**
  35. *
  36. * @author James Ahlborn
  37. */
  38. public class LocalDateTimeTest extends TestCase
  39. {
  40. public LocalDateTimeTest(String name) throws Exception {
  41. super(name);
  42. }
  43. public void testWriteAndReadLocalDate() throws Exception {
  44. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  45. Database db = createMem(fileFormat);
  46. db.setDateTimeType(DateTimeType.LOCAL_DATE_TIME);
  47. Table table = new TableBuilder("test")
  48. .addColumn(new ColumnBuilder("name", DataType.TEXT))
  49. .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME))
  50. .toTable(db);
  51. // since jackcess does not really store millis, shave them off before
  52. // storing the current date/time
  53. long curTimeNoMillis = (System.currentTimeMillis() / 1000L);
  54. curTimeNoMillis *= 1000L;
  55. DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
  56. List<Date> dates =
  57. new ArrayList<Date>(
  58. Arrays.asList(
  59. df.parse("19801231 00:00:00"),
  60. df.parse("19930513 14:43:27"),
  61. null,
  62. df.parse("20210102 02:37:00"),
  63. new Date(curTimeNoMillis)));
  64. Calendar c = Calendar.getInstance();
  65. for(int year = 1801; year < 2050; year +=3) {
  66. for(int month = 0; month <= 12; ++month) {
  67. for(int day = 1; day < 29; day += 3) {
  68. c.clear();
  69. c.set(Calendar.YEAR, year);
  70. c.set(Calendar.MONTH, month);
  71. c.set(Calendar.DAY_OF_MONTH, day);
  72. dates.add(c.getTime());
  73. }
  74. }
  75. }
  76. ((DatabaseImpl)db).getPageChannel().startWrite();
  77. try {
  78. for(Date d : dates) {
  79. table.addRow("row " + d, d);
  80. }
  81. } finally {
  82. ((DatabaseImpl)db).getPageChannel().finishWrite();
  83. }
  84. List<LocalDateTime> foundDates = new ArrayList<LocalDateTime>();
  85. for(Row row : table) {
  86. foundDates.add(row.getLocalDateTime("date"));
  87. }
  88. assertEquals(dates.size(), foundDates.size());
  89. for(int i = 0; i < dates.size(); ++i) {
  90. Date expected = dates.get(i);
  91. LocalDateTime found = foundDates.get(i);
  92. assertSameDate(expected, found);
  93. }
  94. db.close();
  95. }
  96. }
  97. public void testAncientLocalDates() throws Exception
  98. {
  99. ZoneId zoneId = ZoneId.of("America/New_York");
  100. DateTimeFormatter sdf = DateTimeFormatter.ofPattern("uuuu-MM-dd");
  101. List<String> dates = Arrays.asList("1582-10-15", "1582-10-14",
  102. "1492-01-10", "1392-01-10");
  103. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  104. Database db = createMem(fileFormat);
  105. db.setZoneId(zoneId);
  106. db.setDateTimeType(DateTimeType.LOCAL_DATE_TIME);
  107. Table table = new TableBuilder("test")
  108. .addColumn(new ColumnBuilder("name", DataType.TEXT))
  109. .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME))
  110. .toTable(db);
  111. for(String dateStr : dates) {
  112. LocalDate ld = LocalDate.parse(dateStr, sdf);
  113. table.addRow("row " + dateStr, ld);
  114. }
  115. List<String> foundDates = new ArrayList<String>();
  116. for(Row row : table) {
  117. foundDates.add(sdf.format(row.getLocalDateTime("date")));
  118. }
  119. assertEquals(dates, foundDates);
  120. db.close();
  121. }
  122. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.OLD_DATES)) {
  123. Database db = openCopy(testDB);
  124. db.setDateTimeType(DateTimeType.LOCAL_DATE_TIME);
  125. Table t = db.getTable("Table1");
  126. List<String> foundDates = new ArrayList<String>();
  127. for(Row row : t) {
  128. foundDates.add(sdf.format(row.getLocalDateTime("DateField")));
  129. }
  130. assertEquals(dates, foundDates);
  131. db.close();
  132. }
  133. }
  134. public void testZoneId() throws Exception
  135. {
  136. ZoneId zoneId = ZoneId.of("America/New_York");
  137. doTestZoneId(zoneId);
  138. zoneId = ZoneId.of("Australia/Sydney");
  139. doTestZoneId(zoneId);
  140. }
  141. private static void doTestZoneId(final ZoneId zoneId) throws Exception
  142. {
  143. final TimeZone tz = TimeZone.getTimeZone(zoneId);
  144. ColumnImpl col = new ColumnImpl(null, null, DataType.SHORT_DATE_TIME, 0, 0, 0) {
  145. @Override
  146. public TimeZone getTimeZone() { return tz; }
  147. @Override
  148. public ZoneId getZoneId() { return zoneId; }
  149. @Override
  150. public ColumnImpl.DateTimeFactory getDateTimeFactory() {
  151. return getDateTimeFactory(DateTimeType.LOCAL_DATE_TIME);
  152. }
  153. };
  154. SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
  155. df.setTimeZone(tz);
  156. long startDate = df.parse("2012.01.01").getTime();
  157. long endDate = df.parse("2013.01.01").getTime();
  158. Calendar curCal = Calendar.getInstance(tz);
  159. curCal.setTimeInMillis(startDate);
  160. DateTimeFormatter sdf = DateTimeFormatter.ofPattern("uuuu.MM.dd HH:mm:ss");
  161. while(curCal.getTimeInMillis() < endDate) {
  162. Date curDate = curCal.getTime();
  163. LocalDateTime curLdt = LocalDateTime.ofInstant(
  164. Instant.ofEpochMilli(curDate.getTime()), zoneId);
  165. LocalDateTime newLdt = ColumnImpl.ldtFromLocalDateDouble(
  166. col.toDateDouble(curDate));
  167. if(!curLdt.equals(newLdt)) {
  168. System.out.println("FOO " + curLdt + " " + newLdt);
  169. assertEquals(sdf.format(curLdt), sdf.format(newLdt));
  170. }
  171. curCal.add(Calendar.MINUTE, 30);
  172. }
  173. }
  174. public void testWriteAndReadTemporals() throws Exception {
  175. ZoneId zoneId = ZoneId.of("America/New_York");
  176. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  177. Database db = createMem(fileFormat);
  178. db.setZoneId(zoneId);
  179. db.setDateTimeType(DateTimeType.LOCAL_DATE_TIME);
  180. Table table = new TableBuilder("test")
  181. .addColumn(new ColumnBuilder("name", DataType.TEXT))
  182. .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME))
  183. .toTable(db);
  184. // since jackcess does not really store millis, shave them off before
  185. // storing the current date/time
  186. long curTimeNoMillis = (System.currentTimeMillis() / 1000L);
  187. curTimeNoMillis *= 1000L;
  188. DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
  189. List<Date> tmpDates =
  190. new ArrayList<Date>(
  191. Arrays.asList(
  192. df.parse("19801231 00:00:00"),
  193. df.parse("19930513 14:43:27"),
  194. df.parse("20210102 02:37:00"),
  195. new Date(curTimeNoMillis)));
  196. List<Object> objs = new ArrayList<Object>();
  197. List<LocalDateTime> expected = new ArrayList<LocalDateTime>();
  198. for(Date d : tmpDates) {
  199. Instant inst = Instant.ofEpochMilli(d.getTime());
  200. objs.add(inst);
  201. ZonedDateTime zdt = inst.atZone(zoneId);
  202. objs.add(zdt);
  203. LocalDateTime ldt = zdt.toLocalDateTime();
  204. objs.add(ldt);
  205. for(int i = 0; i < 3; ++i) {
  206. expected.add(ldt);
  207. }
  208. }
  209. ((DatabaseImpl)db).getPageChannel().startWrite();
  210. try {
  211. for(Object o : objs) {
  212. table.addRow("row " + o, o);
  213. }
  214. } finally {
  215. ((DatabaseImpl)db).getPageChannel().finishWrite();
  216. }
  217. List<LocalDateTime> foundDates = new ArrayList<LocalDateTime>();
  218. for(Row row : table) {
  219. foundDates.add(row.getLocalDateTime("date"));
  220. }
  221. assertEquals(expected, foundDates);
  222. db.close();
  223. }
  224. }
  225. }