001package com.mrivanplays.annotationconfig.toml;
002
003import com.mrivanplays.annotationconfig.core.serialization.DataObject;
004import com.mrivanplays.annotationconfig.core.serialization.FieldTypeSerializer;
005import java.lang.reflect.Field;
006import java.text.DateFormat;
007import java.text.SimpleDateFormat;
008import java.util.Date;
009import java.util.TimeZone;
010
011/**
012 * Type serializer, which is serializing and deserializing the java 8+ obsolete class {@link Date}.
013 * <br>
014 * This is kept and maintained for backwards compatibility, everyone is encouraged to migrate to the
015 * new java time api.
016 *
017 * @since 1.0
018 */
019public class DateResolver implements FieldTypeSerializer<Date> {
020
021  private static final DateFormat formatter = getFormatter();
022
023  /** {@inheritDoc} */
024  @Override
025  public Date deserialize(DataObject data, Field field) {
026    printWarning();
027    String input = data.getAsString();
028    if (input.indexOf('T') != -1) {
029      String[] dateTimePart = input.split("T");
030      String date = dateTimePart[0];
031      String time = dateTimePart[1];
032      if (!date.contains("-")) {
033        throw new IllegalArgumentException("Invalid date!");
034      }
035      String[] dateParts = date.split("-");
036      int year = Integer.parseInt(dateParts[0]);
037      int month = Integer.parseInt(dateParts[1]);
038      int day = Integer.parseInt(dateParts[2]);
039      if (!time.contains(":")) {
040        throw new IllegalArgumentException("Invalid time!");
041      }
042      String[] timeSplit = time.split(":");
043      int hour = Integer.parseInt(timeSplit[0]);
044      int minute = Integer.parseInt(timeSplit[1]);
045      int second = 0;
046      if (timeSplit.length >= 3) {
047        String secondPart = timeSplit[2];
048        if (secondPart.contains("+") || secondPart.contains("-")) {
049          // fuck timezones. DO NOT USE DATE FOR GOD'S SAKE
050          if (secondPart.indexOf('+') != -1) {
051            secondPart = secondPart.substring(0, secondPart.indexOf('+'));
052          }
053          if (secondPart.indexOf('-') != -1) {
054            secondPart = secondPart.substring(0, secondPart.indexOf('-'));
055          }
056        }
057        second = Integer.parseInt(secondPart);
058      }
059      return new Date(year, month, day, hour, minute, second);
060    } else {
061      // normal date
062      if (!input.contains("-")) {
063        throw new IllegalArgumentException("Invalid date!");
064      }
065      String[] dateParts = input.split("-");
066      int year = Integer.parseInt(dateParts[0]);
067      int month = Integer.parseInt(dateParts[1]);
068      int day = Integer.parseInt(dateParts[2]);
069      return new Date(year, month, day);
070    }
071  }
072
073  /** {@inheritDoc} */
074  @Override
075  public DataObject serialize(Date value, Field field) {
076    printWarning();
077    return new DataObject(formatter.format(value));
078  }
079
080  private void printWarning() {
081    System.err.println(
082        "[AnnotationConfig] WARNING: Stop using Date for dates. Heck, its 2022, we have java 17, and java 8 in 2014 implemented a new time api. USE THAT");
083    System.err.println(
084        "[AnnotationConfig] WARNING: Date serializer is kept and maintained for backwards compatibility, migrate to the new java time API.");
085  }
086
087  private static DateFormat getFormatter() {
088    TimeZone timeZone = TimeZone.getDefault();
089    String format;
090    if (timeZone.getID().contains("UTC")) {
091      format = "yyyy-MM-dd'T'HH:mm:ss'Z'";
092    } else {
093      format = "yyyy-MM-dd'T'HH:mm:ssXXX";
094    }
095    SimpleDateFormat formatter = new SimpleDateFormat(format);
096    formatter.setTimeZone(timeZone);
097    return formatter;
098  }
099}