All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.xpack.core.ml.utils.time.DateTimeFormatterTimestampConverter Maven / Gradle / Ivy

There is a newer version: 8.13.2
Show newest version
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */
package org.elasticsearch.xpack.core.ml.utils.time;

import org.elasticsearch.cli.SuppressForbidden;

import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;

/**
 * 

This class implements {@link TimestampConverter} using the {@link DateTimeFormatter} * of the Java 8 time API for parsing timestamps and other classes of that API for converting * timestamps to epoch times. * *

Objects of this class are immutable and thread-safe * */ public class DateTimeFormatterTimestampConverter implements TimestampConverter { private final DateTimeFormatter formatter; private final boolean hasTimeZone; private final ZoneId defaultZoneId; private DateTimeFormatterTimestampConverter(DateTimeFormatter dateTimeFormatter, boolean hasTimeZone, ZoneId defaultTimezone) { formatter = dateTimeFormatter; this.hasTimeZone = hasTimeZone; defaultZoneId = defaultTimezone; } /** * Creates a formatter according to the given pattern * @param pattern the pattern to be used by the formatter, not null. * See {@link DateTimeFormatter} for the syntax of the accepted patterns * @param defaultTimezone the timezone to be used for dates without timezone information. * @return a {@code TimestampConverter} * @throws IllegalArgumentException if the pattern is invalid or cannot produce a full timestamp * (e.g. contains a date but not a time) */ public static TimestampConverter ofPattern(String pattern, ZoneId defaultTimezone) { DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseLenient() .appendPattern(pattern) .parseDefaulting(ChronoField.YEAR_OF_ERA, LocalDate.now(defaultTimezone).getYear()) .toFormatter(); String formattedTime = formatter.format(ZonedDateTime.ofInstant(Instant.ofEpochSecond(0), ZoneOffset.UTC)); try { TemporalAccessor parsed = formatter.parse(formattedTime); boolean hasTimeZone = parsed.isSupported(ChronoField.INSTANT_SECONDS); if (hasTimeZone) { Instant.from(parsed); } else { LocalDateTime.from(parsed); } return new DateTimeFormatterTimestampConverter(formatter, hasTimeZone, defaultTimezone); } catch (DateTimeException e) { throw new IllegalArgumentException("Timestamp cannot be derived from pattern: " + pattern, e); } } @Override public long toEpochSeconds(String timestamp) { return toInstant(timestamp).getEpochSecond(); } @Override public long toEpochMillis(String timestamp) { return toInstant(timestamp).toEpochMilli(); } private Instant toInstant(String timestamp) { TemporalAccessor parsed = formatter.parse(timestamp); if (hasTimeZone) { return Instant.from(parsed); } return toInstantUnsafelyIgnoringAmbiguity(parsed); } @SuppressForbidden(reason = "TODO https://github.com/elastic/x-pack-elasticsearch/issues/3810") private Instant toInstantUnsafelyIgnoringAmbiguity(TemporalAccessor parsed) { return LocalDateTime.from(parsed).atZone(defaultZoneId).toInstant(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy