diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/DateUtil.java b/pgpainless-core/src/main/java/org/pgpainless/util/DateUtil.java deleted file mode 100644 index f56020d4..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/util/DateUtil.java +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.util; - -import javax.annotation.Nonnull; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -public final class DateUtil { - - private DateUtil() { - - } - - // Java's SimpleDateFormat is not thread-safe, therefore we return a new instance on every invocation. - @Nonnull - public static SimpleDateFormat getParser() { - SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - parser.setTimeZone(TimeZone.getTimeZone("UTC")); - return parser; - } - - /** - * Parse a UTC timestamp into a date. - * - * @param dateString timestamp - * @return date - */ - @Nonnull - public static Date parseUTCDate(@Nonnull String dateString) { - try { - return getParser().parse(dateString); - } catch (ParseException e) { - throw new IllegalArgumentException("Malformed UTC timestamp: " + dateString, e); - } - } - - /** - * Format a date as UTC timestamp. - * - * @param date date - * @return timestamp - */ - @Nonnull - public static String formatUTCDate(Date date) { - return getParser().format(date); - } - - /** - * Floor a date down to seconds precision. - * @param date date - * @return floored date - */ - @Nonnull - public static Date toSecondsPrecision(@Nonnull Date date) { - long millis = date.getTime(); - long seconds = millis / 1000; - long floored = seconds * 1000; - return new Date(floored); - } - - /** - * Return the current date "floored" to UTC precision. - * - * @return now - */ - @Nonnull - public static Date now() { - return toSecondsPrecision(new Date()); - } -} diff --git a/pgpainless-core/src/main/kotlin/openpgp/DateExtensions.kt b/pgpainless-core/src/main/kotlin/openpgp/DateExtensions.kt index db98fb44..5972cd3a 100644 --- a/pgpainless-core/src/main/kotlin/openpgp/DateExtensions.kt +++ b/pgpainless-core/src/main/kotlin/openpgp/DateExtensions.kt @@ -4,20 +4,53 @@ package openpgp +import java.text.ParseException +import java.text.SimpleDateFormat import java.util.* - /** - * Return a new date which represents this date plus the given amount of seconds added. - * - * Since '0' is a special date value in the OpenPGP specification - * (e.g. '0' means no expiration for expiration dates), this method will return 'null' if seconds is 0. - * - * @param date date - * @param seconds number of seconds to be added - * @return date plus seconds or null if seconds is '0' - */ - fun Date.plusSeconds(seconds: Long): Date? { - require(Long.MAX_VALUE - time > seconds) { "Adding $seconds seconds to this date would cause time to overflow." } - return if (seconds == 0L) null - else Date(this.time + 1000 * seconds) +/** + * Return a new date which represents this date plus the given amount of seconds added. + * + * Since '0' is a special date value in the OpenPGP specification + * (e.g. '0' means no expiration for expiration dates), this method will return 'null' if seconds is 0. + * + * @param date date + * @param seconds number of seconds to be added + * @return date plus seconds or null if seconds is '0' + */ +fun Date.plusSeconds(seconds: Long): Date? { + require(Long.MAX_VALUE - time > seconds) { "Adding $seconds seconds to this date would cause time to overflow." } + return if (seconds == 0L) null + else Date(this.time + 1000 * seconds) +} + +/** + * Return a new [Date] instance with this instance's time floored down to seconds precision. + */ +fun Date.toSecondsPrecision(): Date { + return Date((time / 1000) * 1000) +} + +internal val parser: SimpleDateFormat + // Java's SimpleDateFormat is not thread-safe, therefore we return a new instance on every invocation. + get() = SimpleDateFormat("yyyy-MM-dd HH:mm:ss z") + .apply { timeZone = TimeZone.getTimeZone("UTC") } + +/** + * Format a date as UTC timestamp. + * + * @return timestamp + */ +fun Date.formatUTC(): String = parser.format(this) + +/** + * Parse a UTC timestamp into a date. + * @return date + */ +fun String.parseUTC(): Date { + return try { + parser.parse(this) + } catch (e : ParseException) { + throw IllegalArgumentException("Malformed UTC timestamp: $this", e) } +} diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/util/DateUtil.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/util/DateUtil.kt new file mode 100644 index 00000000..de2052d6 --- /dev/null +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/util/DateUtil.kt @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.util + +import openpgp.formatUTC +import openpgp.parseUTC +import openpgp.toSecondsPrecision +import java.util.* + +class DateUtil { + + companion object { + + /** + * Parse a UTC timestamp into a date. + * + * @param dateString timestamp + * @return date + */ + @JvmStatic + fun parseUTCDate(dateString: String): Date = dateString.parseUTC() + + /** + * Format a date as UTC timestamp. + * + * @param date date + * @return timestamp + */ + @JvmStatic + fun formatUTCDate(date: Date): String = date.formatUTC() + + /** + * Floor a date down to seconds precision. + * @param date date + * @return floored date + */ + @JvmStatic + fun toSecondsPrecision(date: Date): Date = date.toSecondsPrecision() + + /** + * Return the current date "floored" to UTC precision. + * + * @return now + */ + @JvmStatic + fun now() = toSecondsPrecision(Date()) + } +} \ No newline at end of file