/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java

https://github.com/alibaba/fastjson · Java · 636 lines · 569 code · 67 blank · 0 comment · 329 complexity · fb50dcf0e97a28ec1d87a106c1301073 MD5 · raw file

  1. package com.alibaba.fastjson.parser.deserializer;
  2. import java.io.IOException;
  3. import java.lang.reflect.Type;
  4. import java.time.Duration;
  5. import java.time.Instant;
  6. import java.time.LocalDate;
  7. import java.time.LocalDateTime;
  8. import java.time.LocalTime;
  9. import java.time.OffsetDateTime;
  10. import java.time.OffsetTime;
  11. import java.time.Period;
  12. import java.time.ZoneId;
  13. import java.time.ZonedDateTime;
  14. import java.time.chrono.ChronoZonedDateTime;
  15. import java.time.format.DateTimeFormatter;
  16. import java.time.temporal.TemporalAccessor;
  17. import java.util.Date;
  18. import java.util.Locale;
  19. import java.util.TimeZone;
  20. import com.alibaba.fastjson.JSON;
  21. import com.alibaba.fastjson.JSONObject;
  22. import com.alibaba.fastjson.parser.DefaultJSONParser;
  23. import com.alibaba.fastjson.parser.JSONLexer;
  24. import com.alibaba.fastjson.parser.JSONScanner;
  25. import com.alibaba.fastjson.parser.JSONToken;
  26. import com.alibaba.fastjson.serializer.*;
  27. import com.alibaba.fastjson.util.TypeUtils;
  28. public class Jdk8DateCodec extends ContextObjectDeserializer implements ObjectSerializer, ContextObjectSerializer, ObjectDeserializer {
  29. public static final Jdk8DateCodec instance = new Jdk8DateCodec();
  30. private final static String defaultPatttern = "yyyy-MM-dd HH:mm:ss";
  31. private final static DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern(defaultPatttern);
  32. private final static DateTimeFormatter defaultFormatter_23 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
  33. private final static DateTimeFormatter formatter_dt19_tw = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
  34. private final static DateTimeFormatter formatter_dt19_cn = DateTimeFormatter.ofPattern("yyyy年M月d日 HH:mm:ss");
  35. private final static DateTimeFormatter formatter_dt19_cn_1 = DateTimeFormatter.ofPattern("yyyy年M月d日 H时m分s秒");
  36. private final static DateTimeFormatter formatter_dt19_kr = DateTimeFormatter.ofPattern("yyyy년M월d일 HH:mm:ss");
  37. private final static DateTimeFormatter formatter_dt19_us = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
  38. private final static DateTimeFormatter formatter_dt19_eur = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
  39. private final static DateTimeFormatter formatter_dt19_de = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
  40. private final static DateTimeFormatter formatter_dt19_in = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
  41. private final static DateTimeFormatter formatter_d8 = DateTimeFormatter.ofPattern("yyyyMMdd");
  42. private final static DateTimeFormatter formatter_d10_tw = DateTimeFormatter.ofPattern("yyyy/MM/dd");
  43. private final static DateTimeFormatter formatter_d10_cn = DateTimeFormatter.ofPattern("yyyy年M月d日");
  44. private final static DateTimeFormatter formatter_d10_kr = DateTimeFormatter.ofPattern("yyyy년M월d일");
  45. private final static DateTimeFormatter formatter_d10_us = DateTimeFormatter.ofPattern("MM/dd/yyyy");
  46. private final static DateTimeFormatter formatter_d10_eur = DateTimeFormatter.ofPattern("dd/MM/yyyy");
  47. private final static DateTimeFormatter formatter_d10_de = DateTimeFormatter.ofPattern("dd.MM.yyyy");
  48. private final static DateTimeFormatter formatter_d10_in = DateTimeFormatter.ofPattern("dd-MM-yyyy");
  49. private final static DateTimeFormatter ISO_FIXED_FORMAT =
  50. DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
  51. private final static String formatter_iso8601_pattern = "yyyy-MM-dd'T'HH:mm:ss";
  52. private final static String formatter_iso8601_pattern_23 = "yyyy-MM-dd'T'HH:mm:ss.SSS";
  53. private final static String formatter_iso8601_pattern_29 = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS";
  54. private final static DateTimeFormatter formatter_iso8601 = DateTimeFormatter.ofPattern(formatter_iso8601_pattern);
  55. @SuppressWarnings("unchecked")
  56. public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName, String format, int feature) {
  57. JSONLexer lexer = parser.lexer;
  58. if (lexer.token() == JSONToken.NULL){
  59. lexer.nextToken();
  60. return null;
  61. }
  62. if (lexer.token() == JSONToken.LITERAL_STRING) {
  63. String text = lexer.stringVal();
  64. lexer.nextToken();
  65. DateTimeFormatter formatter = null;
  66. if (format != null) {
  67. if (defaultPatttern.equals(format)) {
  68. formatter = defaultFormatter;
  69. } else {
  70. formatter = DateTimeFormatter.ofPattern(format);
  71. }
  72. }
  73. if ("".equals(text)) {
  74. return null;
  75. }
  76. if (type == LocalDateTime.class) {
  77. LocalDateTime localDateTime;
  78. if (text.length() == 10 || text.length() == 8) {
  79. LocalDate localDate = parseLocalDate(text, format, formatter);
  80. localDateTime = LocalDateTime.of(localDate, LocalTime.MIN);
  81. } else {
  82. localDateTime = parseDateTime(text, formatter);
  83. }
  84. return (T) localDateTime;
  85. } else if (type == LocalDate.class) {
  86. LocalDate localDate;
  87. if (text.length() == 23) {
  88. LocalDateTime localDateTime = LocalDateTime.parse(text);
  89. localDate = LocalDate.of(localDateTime.getYear(), localDateTime.getMonthValue(),
  90. localDateTime.getDayOfMonth());
  91. } else {
  92. localDate = parseLocalDate(text, format, formatter);
  93. }
  94. return (T) localDate;
  95. } else if (type == LocalTime.class) {
  96. LocalTime localTime;
  97. if (text.length() == 23) {
  98. LocalDateTime localDateTime = LocalDateTime.parse(text);
  99. localTime = LocalTime.of(localDateTime.getHour(), localDateTime.getMinute(),
  100. localDateTime.getSecond(), localDateTime.getNano());
  101. } else {
  102. boolean digit = true;
  103. for (int i = 0; i < text.length(); ++i) {
  104. char ch = text.charAt(i);
  105. if (ch < '0' || ch > '9') {
  106. digit = false;
  107. break;
  108. }
  109. }
  110. if (digit && text.length() > 8 && text.length() < 19) {
  111. long epochMillis = Long.parseLong(text);
  112. localTime = LocalDateTime
  113. .ofInstant(
  114. Instant.ofEpochMilli(epochMillis),
  115. JSON.defaultTimeZone.toZoneId())
  116. .toLocalTime();
  117. } else {
  118. localTime = LocalTime.parse(text);
  119. }
  120. }
  121. return (T) localTime;
  122. } else if (type == ZonedDateTime.class) {
  123. if (formatter == defaultFormatter) {
  124. formatter = ISO_FIXED_FORMAT;
  125. }
  126. if (formatter == null) {
  127. if (text.length() <= 19) {
  128. JSONScanner s = new JSONScanner(text);
  129. TimeZone timeZone = parser.lexer.getTimeZone();
  130. s.setTimeZone(timeZone);
  131. boolean match = s.scanISO8601DateIfMatch(false);
  132. if (match) {
  133. Date date = s.getCalendar().getTime();
  134. return (T) ZonedDateTime.ofInstant(date.toInstant(), timeZone.toZoneId());
  135. }
  136. }
  137. }
  138. ZonedDateTime zonedDateTime = parseZonedDateTime(text, formatter);
  139. return (T) zonedDateTime;
  140. } else if (type == OffsetDateTime.class) {
  141. OffsetDateTime offsetDateTime = OffsetDateTime.parse(text);
  142. return (T) offsetDateTime;
  143. } else if (type == OffsetTime.class) {
  144. OffsetTime offsetTime = OffsetTime.parse(text);
  145. return (T) offsetTime;
  146. } else if (type == ZoneId.class) {
  147. ZoneId offsetTime = ZoneId.of(text);
  148. return (T) offsetTime;
  149. } else if (type == Period.class) {
  150. Period period = Period.parse(text);
  151. return (T) period;
  152. } else if (type == Duration.class) {
  153. Duration duration = Duration.parse(text);
  154. return (T) duration;
  155. } else if (type == Instant.class) {
  156. boolean digit = true;
  157. for (int i = 0; i < text.length(); ++i) {
  158. char ch = text.charAt(i);
  159. if (ch < '0' || ch > '9') {
  160. digit = false;
  161. break;
  162. }
  163. }
  164. if (digit && text.length() > 8 && text.length() < 19) {
  165. long epochMillis = Long.parseLong(text);
  166. return (T) Instant.ofEpochMilli(epochMillis);
  167. }
  168. Instant instant = Instant.parse(text);
  169. return (T) instant;
  170. }
  171. } else if (lexer.token() == JSONToken.LITERAL_INT) {
  172. long millis = lexer.longValue();
  173. lexer.nextToken();
  174. if ("unixtime".equals(format)) {
  175. millis *= 1000;
  176. } else if ("yyyyMMddHHmmss".equals(format)) {
  177. int yyyy = (int) (millis / 10000000000L);
  178. int MM = (int) ((millis / 100000000L) % 100);
  179. int dd = (int) ((millis / 1000000L) % 100);
  180. int HH = (int) ((millis / 10000L) % 100);
  181. int mm = (int) ((millis / 100L) % 100);
  182. int ss = (int) (millis % 100);
  183. if (type == LocalDateTime.class) {
  184. return (T) LocalDateTime.of(yyyy, MM, dd, HH, mm, ss);
  185. }
  186. }
  187. if (type == LocalDateTime.class) {
  188. return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId());
  189. }
  190. if (type == LocalDate.class) {
  191. return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId()).toLocalDate();
  192. }
  193. if (type == LocalTime.class) {
  194. return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId()).toLocalTime();
  195. }
  196. if (type == ZonedDateTime.class) {
  197. return (T) ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId());
  198. }
  199. if (type == Instant.class) {
  200. return (T) Instant.ofEpochMilli(millis);
  201. }
  202. throw new UnsupportedOperationException();
  203. } else if (lexer.token() == JSONToken.LBRACE) {
  204. JSONObject object = parser.parseObject();
  205. if (type == Instant.class) {
  206. Object epochSecond = object.get("epochSecond");
  207. Object nano = object.get("nano");
  208. if (epochSecond instanceof Number && nano instanceof Number) {
  209. return (T) Instant.ofEpochSecond(
  210. TypeUtils.longExtractValue((Number) epochSecond)
  211. , TypeUtils.longExtractValue((Number) nano));
  212. }
  213. if (epochSecond instanceof Number) {
  214. return (T) Instant.ofEpochSecond(
  215. TypeUtils.longExtractValue((Number) epochSecond));
  216. }
  217. } else if (type == Duration.class) {
  218. Long seconds = object.getLong("seconds");
  219. if (seconds != null) {
  220. long nanos = object.getLongValue("nano");
  221. return (T) Duration.ofSeconds(seconds, nanos);
  222. }
  223. }
  224. } else {
  225. throw new UnsupportedOperationException();
  226. }
  227. return null;
  228. }
  229. protected LocalDateTime parseDateTime(String text, DateTimeFormatter formatter) {
  230. if (formatter == null) {
  231. if (text.length() == 19) {
  232. char c4 = text.charAt(4);
  233. char c7 = text.charAt(7);
  234. char c10 = text.charAt(10);
  235. char c13 = text.charAt(13);
  236. char c16 = text.charAt(16);
  237. if (c13 == ':' && c16 == ':') {
  238. if (c4 == '-' && c7 == '-') {
  239. if (c10 == 'T') {
  240. formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
  241. } else if (c10 == ' ') {
  242. formatter = defaultFormatter;
  243. }
  244. } else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd
  245. formatter = formatter_dt19_tw;
  246. } else {
  247. char c0 = text.charAt(0);
  248. char c1 = text.charAt(1);
  249. char c2 = text.charAt(2);
  250. char c3 = text.charAt(3);
  251. char c5 = text.charAt(5);
  252. if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy
  253. int v0 = (c0 - '0') * 10 + (c1 - '0');
  254. int v1 = (c3 - '0') * 10 + (c4 - '0');
  255. if (v0 > 12) {
  256. formatter = formatter_dt19_eur;
  257. } else if (v1 > 12) {
  258. formatter = formatter_dt19_us;
  259. } else {
  260. String country = Locale.getDefault().getCountry();
  261. if (country.equals("US")) {
  262. formatter = formatter_dt19_us;
  263. } else if (country.equals("BR") //
  264. || country.equals("AU")) {
  265. formatter = formatter_dt19_eur;
  266. }
  267. }
  268. } else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy
  269. formatter = formatter_dt19_de;
  270. } else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy
  271. formatter = formatter_dt19_in;
  272. }
  273. }
  274. }
  275. } else if (text.length() == 23) {
  276. char c4 = text.charAt(4);
  277. char c7 = text.charAt(7);
  278. char c10 = text.charAt(10);
  279. char c13 = text.charAt(13);
  280. char c16 = text.charAt(16);
  281. char c19 = text.charAt(19);
  282. if (c13 == ':'
  283. && c16 == ':'
  284. && c4 == '-'
  285. && c7 == '-'
  286. && c10 == ' '
  287. && c19 == '.'
  288. ) {
  289. formatter = defaultFormatter_23;
  290. }
  291. }
  292. if (text.length() >= 17) {
  293. char c4 = text.charAt(4);
  294. if (c4 == '年') {
  295. if (text.charAt(text.length() - 1) == '秒') {
  296. formatter = formatter_dt19_cn_1;
  297. } else {
  298. formatter = formatter_dt19_cn;
  299. }
  300. } else if (c4 == '년') {
  301. formatter = formatter_dt19_kr;
  302. }
  303. }
  304. }
  305. if (formatter == null) {
  306. JSONScanner dateScanner = new JSONScanner(text);
  307. if (dateScanner.scanISO8601DateIfMatch(false)) {
  308. Instant instant = dateScanner.getCalendar().toInstant();
  309. return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
  310. }
  311. boolean digit = true;
  312. for (int i = 0; i < text.length(); ++i) {
  313. char ch = text.charAt(i);
  314. if (ch < '0' || ch > '9') {
  315. digit = false;
  316. break;
  317. }
  318. }
  319. if (digit && text.length() > 8 && text.length() < 19) {
  320. long epochMillis = Long.parseLong(text);
  321. return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), JSON.defaultTimeZone.toZoneId());
  322. }
  323. }
  324. return formatter == null ? //
  325. LocalDateTime.parse(text) //
  326. : LocalDateTime.parse(text, formatter);
  327. }
  328. protected LocalDate parseLocalDate(String text, String format, DateTimeFormatter formatter) {
  329. if (formatter == null) {
  330. if (text.length() == 8) {
  331. formatter = formatter_d8;
  332. }
  333. if (text.length() == 10) {
  334. char c4 = text.charAt(4);
  335. char c7 = text.charAt(7);
  336. if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd
  337. formatter = formatter_d10_tw;
  338. }
  339. char c0 = text.charAt(0);
  340. char c1 = text.charAt(1);
  341. char c2 = text.charAt(2);
  342. char c3 = text.charAt(3);
  343. char c5 = text.charAt(5);
  344. if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy
  345. int v0 = (c0 - '0') * 10 + (c1 - '0');
  346. int v1 = (c3 - '0') * 10 + (c4 - '0');
  347. if (v0 > 12) {
  348. formatter = formatter_d10_eur;
  349. } else if (v1 > 12) {
  350. formatter = formatter_d10_us;
  351. } else {
  352. String country = Locale.getDefault().getCountry();
  353. if (country.equals("US")) {
  354. formatter = formatter_d10_us;
  355. } else if (country.equals("BR") //
  356. || country.equals("AU")) {
  357. formatter = formatter_d10_eur;
  358. }
  359. }
  360. } else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy
  361. formatter = formatter_d10_de;
  362. } else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy
  363. formatter = formatter_d10_in;
  364. }
  365. }
  366. if (text.length() >= 9) {
  367. char c4 = text.charAt(4);
  368. if (c4 == '年') {
  369. formatter = formatter_d10_cn;
  370. } else if (c4 == '년') {
  371. formatter = formatter_d10_kr;
  372. }
  373. }
  374. boolean digit = true;
  375. for (int i = 0; i < text.length(); ++i) {
  376. char ch = text.charAt(i);
  377. if (ch < '0' || ch > '9') {
  378. digit = false;
  379. break;
  380. }
  381. }
  382. if (digit && text.length() > 8 && text.length() < 19) {
  383. long epochMillis = Long.parseLong(text);
  384. return LocalDateTime
  385. .ofInstant(
  386. Instant.ofEpochMilli(epochMillis),
  387. JSON.defaultTimeZone.toZoneId())
  388. .toLocalDate();
  389. }
  390. }
  391. return formatter == null ? //
  392. LocalDate.parse(text) //
  393. : LocalDate.parse(text, formatter);
  394. }
  395. protected ZonedDateTime parseZonedDateTime(String text, DateTimeFormatter formatter) {
  396. if (formatter == null) {
  397. if (text.length() == 19) {
  398. char c4 = text.charAt(4);
  399. char c7 = text.charAt(7);
  400. char c10 = text.charAt(10);
  401. char c13 = text.charAt(13);
  402. char c16 = text.charAt(16);
  403. if (c13 == ':' && c16 == ':') {
  404. if (c4 == '-' && c7 == '-') {
  405. if (c10 == 'T') {
  406. formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
  407. } else if (c10 == ' ') {
  408. formatter = defaultFormatter;
  409. }
  410. } else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd
  411. formatter = formatter_dt19_tw;
  412. } else {
  413. char c0 = text.charAt(0);
  414. char c1 = text.charAt(1);
  415. char c2 = text.charAt(2);
  416. char c3 = text.charAt(3);
  417. char c5 = text.charAt(5);
  418. if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy
  419. int v0 = (c0 - '0') * 10 + (c1 - '0');
  420. int v1 = (c3 - '0') * 10 + (c4 - '0');
  421. if (v0 > 12) {
  422. formatter = formatter_dt19_eur;
  423. } else if (v1 > 12) {
  424. formatter = formatter_dt19_us;
  425. } else {
  426. String country = Locale.getDefault().getCountry();
  427. if (country.equals("US")) {
  428. formatter = formatter_dt19_us;
  429. } else if (country.equals("BR") //
  430. || country.equals("AU")) {
  431. formatter = formatter_dt19_eur;
  432. }
  433. }
  434. } else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy
  435. formatter = formatter_dt19_de;
  436. } else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy
  437. formatter = formatter_dt19_in;
  438. }
  439. }
  440. }
  441. }
  442. if (text.length() >= 17) {
  443. char c4 = text.charAt(4);
  444. if (c4 == '年') {
  445. if (text.charAt(text.length() - 1) == '秒') {
  446. formatter = formatter_dt19_cn_1;
  447. } else {
  448. formatter = formatter_dt19_cn;
  449. }
  450. } else if (c4 == '년') {
  451. formatter = formatter_dt19_kr;
  452. }
  453. }
  454. boolean digit = true;
  455. for (int i = 0; i < text.length(); ++i) {
  456. char ch = text.charAt(i);
  457. if (ch < '0' || ch > '9') {
  458. digit = false;
  459. break;
  460. }
  461. }
  462. if (digit && text.length() > 8 && text.length() < 19) {
  463. long epochMillis = Long.parseLong(text);
  464. return ZonedDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), JSON.defaultTimeZone.toZoneId());
  465. }
  466. }
  467. return formatter == null ? //
  468. ZonedDateTime.parse(text) //
  469. : ZonedDateTime.parse(text, formatter);
  470. }
  471. public int getFastMatchToken() {
  472. return JSONToken.LITERAL_STRING;
  473. }
  474. public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
  475. int features) throws IOException {
  476. SerializeWriter out = serializer.out;
  477. if (object == null) {
  478. out.writeNull();
  479. } else {
  480. if (fieldType == null) {
  481. fieldType = object.getClass();
  482. }
  483. if (fieldType == LocalDateTime.class) {
  484. final int mask = SerializerFeature.UseISO8601DateFormat.getMask();
  485. LocalDateTime dateTime = (LocalDateTime) object;
  486. String format = serializer.getDateFormatPattern();
  487. if (format == null) {
  488. if ((features & mask) != 0 || serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) {
  489. format = formatter_iso8601_pattern;
  490. } else if (serializer.isEnabled(SerializerFeature.WriteDateUseDateFormat)) {
  491. if (serializer.getFastJsonConfigDateFormatPattern() != null &&
  492. serializer.getFastJsonConfigDateFormatPattern().length() > 0){
  493. format = serializer.getFastJsonConfigDateFormatPattern();
  494. }else{
  495. format = JSON.DEFFAULT_DATE_FORMAT;
  496. }
  497. } else {
  498. int nano = dateTime.getNano();
  499. if (nano == 0) {
  500. format = formatter_iso8601_pattern;
  501. } else if (nano % 1000000 == 0) {
  502. format = formatter_iso8601_pattern_23;
  503. } else {
  504. format = formatter_iso8601_pattern_29;
  505. }
  506. }
  507. }
  508. if (format != null) {
  509. write(out, dateTime, format);
  510. } else {
  511. out.writeLong(dateTime.atZone(JSON.defaultTimeZone.toZoneId()).toInstant().toEpochMilli());
  512. }
  513. } else {
  514. out.writeString(object.toString());
  515. }
  516. }
  517. }
  518. public void write(JSONSerializer serializer, Object object, BeanContext context) throws IOException {
  519. SerializeWriter out = serializer.out;
  520. String format = context.getFormat();
  521. write(out, (TemporalAccessor) object, format);
  522. }
  523. private void write(SerializeWriter out, TemporalAccessor object, String format) {
  524. DateTimeFormatter formatter;
  525. if ("unixtime".equals(format)) {
  526. Instant instant = null;
  527. if (object instanceof ChronoZonedDateTime) {
  528. long seconds = ((ChronoZonedDateTime) object).toEpochSecond();
  529. out.writeInt((int) seconds);
  530. return;
  531. }
  532. if (object instanceof LocalDateTime) {
  533. long seconds = ((LocalDateTime) object).atZone(JSON.defaultTimeZone.toZoneId()).toEpochSecond();
  534. out.writeInt((int) seconds);
  535. return;
  536. }
  537. }
  538. if ("millis".equals(format)) {
  539. Instant instant = null;
  540. if (object instanceof ChronoZonedDateTime) {
  541. instant = ((ChronoZonedDateTime) object).toInstant();
  542. } else if (object instanceof LocalDateTime) {
  543. instant = ((LocalDateTime) object).atZone(JSON.defaultTimeZone.toZoneId()).toInstant();
  544. }
  545. if (instant != null) {
  546. long millis = instant.toEpochMilli();
  547. out.writeLong(millis);
  548. return;
  549. }
  550. }
  551. if (format == formatter_iso8601_pattern) {
  552. formatter = formatter_iso8601;
  553. } else {
  554. formatter = DateTimeFormatter.ofPattern(format);
  555. }
  556. String text = formatter.format((TemporalAccessor) object);
  557. out.writeString(text);
  558. }
  559. public static Object castToLocalDateTime(Object value, String format) {
  560. if (value == null) {
  561. return null;
  562. }
  563. if (format == null) {
  564. format = "yyyy-MM-dd HH:mm:ss";
  565. }
  566. DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
  567. return LocalDateTime.parse(value.toString(), df);
  568. }
  569. }