当前位置: 首页 > article >正文

neo4j 中日期时间 时间戳处理

### 使用指定格式(默认ISO)和指定时区(默认当前TZ),使用指定单位(默认ms)获取时间值的字符串表示形式(可选)

测试

return apoc.date.format(1729380807273,('ms'),('yyyy-MM-dd HH:mm:ss zzz'),('TZ'))
return apoc.date.format(1729380807,('s'),('yyyy-MM-dd HH:mm:ss zzz'),('TZ'))
//"2024-10-19 23:33:27 GMT" 


return apoc.date.format(1729380807273,('ms'),('yyyy-MM-dd HH:mm:ss'))
// "2024-10-19 23:33:27"  


return apoc.date.format(1729380807273)  
// "2024-10-19 23:33:27"  

源码

// 源码 package apoc.date; 这些函数主要位于apoc.temporal和apoc.date包下。

// ../gits/apoc-4.2/core/src/main/java/apoc/date/Date.java

package apoc.date;

import apoc.util.DateFormatUtil;
import apoc.util.Util;
import org.apache.commons.lang3.StringUtils;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.procedure.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
import java.time.temporal.TemporalQuery;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import static java.time.temporal.ChronoField.*;


/**
 * @author tkroman
 * @since 9.04.2016
 */
public class Date {
	public static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
	private static final int MILLIS_IN_SECOND = 1000;
	private static final String UTC_ZONE_ID = "UTC";
	private static final List<TemporalQuery<Consumer<FieldResult>>> DT_FIELDS_SELECTORS = Arrays.asList(
			temporalQuery(YEAR),
			temporalQuery(MONTH_OF_YEAR),
			temporalQuery(DAY_OF_WEEK),
			temporalQuery(DAY_OF_MONTH),
			temporalQuery(HOUR_OF_DAY),
			temporalQuery(MINUTE_OF_HOUR),
			temporalQuery(SECOND_OF_MINUTE),
			(temporal) -> (FieldResult result) -> {
				Optional<ZoneId> zone = Optional.ofNullable(TemporalQueries.zone().queryFrom(temporal));
				zone.ifPresent(zoneId -> {
					String displayName = zoneId.getDisplayName(TextStyle.SHORT, Locale.ROOT);
					result.value.put("zoneid", displayName);
					result.zoneid = displayName;
				});
			}
	);

	@UserFunction
	@Description("toYears(timestamp) or toYears(date[,format]) - converts timestamp into floating point years")
	public double toYears(@Name("value") Object value, @Name(value = "format", defaultValue = DEFAULT_FORMAT) String format) {
		if (value instanceof Number) {
			long time = ((Number) value).longValue();
			return (time / (365d*24*3600*1000));
		} else {
			long time = parse(value.toString(),"ms",format,null);
			return 1970d + (time / (365d*24*3600*1000));
		}
	}

	@UserFunction
	@Description("apoc.date.fields('2012-12-23',('yyyy-MM-dd')) - return columns and a map representation of date parsed with the given format with entries for years,months,weekdays,days,hours,minutes,seconds,zoneid")
	public Map<String,Object> fields(final @Name("date") String date, final @Name(value = "pattern", defaultValue = DEFAULT_FORMAT) String pattern) {
		if (date == null) {
			return Util.map();
		}
		DateTimeFormatter fmt = getSafeDateTimeFormatter(pattern);
		TemporalAccessor temporal = fmt.parse(date);
		FieldResult result = new FieldResult();

		for (final TemporalQuery<Consumer<FieldResult>> query : DT_FIELDS_SELECTORS) {
			query.queryFrom(temporal).accept(result);
		}

		return result.asMap();
	}

	@UserFunction
	@Description("apoc.date.field(12345,('ms|s|m|h|d|month|year'),('TZ')")
	public Long field(final @Name("time") Long time,  @Name(value = "unit", defaultValue = "d") String unit, @Name(value = "timezone",defaultValue = "UTC") String timezone) {
		return (time == null)
				? null
				: (long) ZonedDateTime
				.ofInstant( Instant.ofEpochMilli( time ), ZoneId.of( timezone ) )
				.get( chronoField( unit ) );
	}

	@UserFunction
	@Description( "apoc.date.currentTimestamp() - returns System.currentTimeMillis() at the time it was called. The value is current throughout transaction execution, and is different from Cypher’s timestamp() function, which does not update within a transaction." )
	public long currentTimestamp()
	{
		return System.currentTimeMillis();
	}

	public static class FieldResult {
		public final Map<String,Object> value = new LinkedHashMap<>();
		public long years, months, days, weekdays, hours, minutes, seconds;
		public String zoneid;

		public Map<String, Object> asMap() {
			return value;
		}
	}

	public static TimeUnit unit(String unit) {
		if (unit == null) return TimeUnit.MILLISECONDS;

		switch (unit.toLowerCase()) {
			case "ms": case "milli":  case "millis": case "milliseconds": return TimeUnit.MILLISECONDS;
			case "s":  case "second": case "seconds": return TimeUnit.SECONDS;
			case "m":  case "minute": case "minutes": return TimeUnit.MINUTES;
			case "h":  case "hour":   case "hours":   return TimeUnit.HOURS;
			case "d":  case "day":    case "days":    return TimeUnit.DAYS;
//			case "month":case "months": return TimeUnit.MONTHS;
//			case "years":case "year": return TimeUnit.YEARS;
		}

		throw new IllegalArgumentException("The unit: "+ unit + " is not correct");

		//return TimeUnit.MILLISECONDS;
	}

	private ChronoField chronoField(String unit) {
		switch (unit.toLowerCase()) {
			case "ms": case "milli":  case "millis": case "milliseconds": return ChronoField.MILLI_OF_SECOND;
			case "s":  case "second": case "seconds": return ChronoField.SECOND_OF_MINUTE;
			case "m":  case "minute": case "minutes": return ChronoField.MINUTE_OF_HOUR;
			case "h":  case "hour":   case "hours":   return ChronoField.HOUR_OF_DAY;
			case "d":  case "day":    case "days":    return ChronoField.DAY_OF_MONTH;
			case "w":  case "weekday": case "weekdays": return ChronoField.DAY_OF_WEEK;
			case "month":case "months": return ChronoField.MONTH_OF_YEAR;
			case "year":case "years": return ChronoField.YEAR;
//			default: return ChronoField.YEAR;
		}

		throw new IllegalArgumentException("The unit: "+ unit + " is not correct");
	}

	@UserFunction
	@Description("apoc.date.format(12345,('ms|s|m|h|d'),('yyyy-MM-dd HH:mm:ss zzz'),('TZ')) - get string representation of time value optionally using the specified unit (default ms) using specified format (default ISO) and specified time zone (default current TZ)")
	public String format(final @Name("time") Long time, @Name(value = "unit", defaultValue = "ms") String unit, @Name(value = "format",defaultValue = DEFAULT_FORMAT) String format, @Name(value = "timezone",defaultValue = "") String timezone) {
		return time == null ? null : parse(unit(unit).toMillis(time), format, timezone);
	}

	@UserFunction
	@Description("apoc.date.toISO8601(12345,('ms|s|m|h|d') - return string representation of time in ISO8601 format")
	public String toISO8601(final @Name("time") Long time, @Name(value = "unit", defaultValue = "ms") String unit) {
		return time == null ? null : parse(unit(unit).toMillis(time), "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", null);
	}

	@UserFunction
	@Description("apoc.date.fromISO8601('yyyy-MM-ddTHH:mm:ss.SSSZ') - return number representation of time in EPOCH format")
	public Long fromISO8601(final @Name("time") String time) {
		return time == null ? null : Instant.parse(time).toEpochMilli();
	}

	@UserFunction
	@Description("apoc.date.parse('2012-12-23','ms|s|m|h|d','yyyy-MM-dd') - parse date string using the specified format into the specified time unit")
	public Long parse(@Name("time") String time, @Name(value = "unit", defaultValue = "ms") String unit, @Name(value = "format",defaultValue = DEFAULT_FORMAT) String format, final @Name(value = "timezone", defaultValue = "") String timezone) {
		Long value = StringUtils.isBlank(time) ? null : parseOrThrow(time, getFormat(format, timezone));
		return value == null ? null : unit(unit).convert(value, TimeUnit.MILLISECONDS);
	}

	@UserFunction(deprecatedBy = "apoc.temporal.toZonedTemporal")
	@Description("apoc.date.parseAsZonedDateTime('2012-12-23 23:59:59','yyyy-MM-dd HH:mm:ss', 'UTC-hour-offset') - parse date string using the specified format to specified timezone")
	@Deprecated
	public ZonedDateTime parseAsZonedDateTime(@Name("time") String time, @Name(value = "format", defaultValue = DEFAULT_FORMAT) String format, final @Name(value = "timezone", defaultValue = "UTC") String timezone) {
		Long value = parseOrThrow(time, getFormat(format, timezone));
		return value == null ? null : Instant.ofEpochMilli(value).atZone(ZoneId.of(timezone));
	}

	@UserFunction
	@Description("apoc.date.systemTimezone() - returns the system timezone display name")
	public String systemTimezone() {
		return TimeZone.getDefault().getID();
	}

	@UserFunction
	@Description("apoc.date.convert(12345, 'ms', 'd') - convert a timestamp in one time unit into one of a different time unit")
	public Long convert(@Name("time") long time, @Name(value = "unit") String unit, @Name(value = "toUnit") String toUnit) {
		return unit(toUnit).convert(time, unit(unit));
	}

	@UserFunction
	@Description("apoc.date.convertFormat('Tue, 14 May 2019 14:52:06 -0400', 'rfc_1123_date_time', 'iso_date_time') - convert a String of one date format into a String of another date format.")
	public String convertFormat( @Name( "temporal" ) String input, @Name( value = "currentFormat" ) String currentFormat, @Name( value = "convertTo" , defaultValue = "yyyy-MM-dd" ) String convertTo )
	{
		if (input == null || input.isEmpty())
		{
			return null;
		}

		DateTimeFormatter currentFormatter = DateFormatUtil.getOrCreate( currentFormat );
		DateTimeFormatter convertToFormatter = DateFormatUtil.getOrCreate( convertTo );

		return convertToFormatter.format(  currentFormatter.parse( input ) );
	}

	@UserFunction
	@Description("apoc.date.add(12345, 'ms', -365, 'd') - given a timestamp in one time unit, adds a value of the specified time unit")
	public Long add(@Name("time") long time, @Name(value = "unit") String unit, @Name(value = "addValue") long addValue, @Name(value = "addUnit") String addUnit) {
		long valueToAdd = unit(unit).convert(addValue, unit(addUnit));
		return time + valueToAdd;
	}

	public String parse(final @Name("millis") long millis, final @Name(value = "pattern", defaultValue = DEFAULT_FORMAT) String pattern, final @Name("timezone") String timezone) {
		return getFormat(pattern, timezone).format(new java.util.Date(millis));
	}

	public static DateFormat getFormat(final String pattern, final String timezone) {
		String actualPattern = getPattern(pattern);
		SimpleDateFormat format = null;
		try {
			format = new SimpleDateFormat(actualPattern);
		} catch(Exception e){
			throw new IllegalArgumentException("The pattern: "+pattern+" is not correct");
		}
		if (timezone != null && !"".equals(timezone)) {
			format.setTimeZone(TimeZone.getTimeZone(timezone));
		} else if (!(containsTimeZonePattern(actualPattern))) {
			format.setTimeZone(TimeZone.getTimeZone(UTC_ZONE_ID));
		}
		return format;
	}

	//work around https://bugs.openjdk.java.net/browse/JDK-8139107
	private static DateTimeFormatter getSafeDateTimeFormatter(final String pattern) {
		DateTimeFormatter safeFormatter = getDateTimeFormatter(pattern);

		if (Locale.UK.equals(safeFormatter.getLocale())) {
			return safeFormatter.withLocale(Locale.ENGLISH);
		}

		return safeFormatter;
	}

	private static DateTimeFormatter getDateTimeFormatter(final String pattern) {
		String actualPattern = getPattern(pattern);
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern(actualPattern);
		if (containsTimeZonePattern(actualPattern)) {
			return fmt;
		} else {
			return fmt.withZone(ZoneId.of(UTC_ZONE_ID));
		}
	}

	public  static Long parseOrThrow(final String date, final DateFormat format) {
		if (date == null) return null;
		try {
			return format.parse(date).getTime();
		} catch (ParseException e) {
			throw new IllegalArgumentException(e);
		}
	}

	private static boolean containsTimeZonePattern(final String pattern) {
		return pattern.matches("[XxZzVO]{1,3}");	// doesn't account for strings escaped with "'" (TODO?)
	}

	private static String getPattern(final String pattern) {
		return pattern == null || "".equals(pattern) ? DEFAULT_FORMAT : pattern;
	}

	private static TemporalQuery<Consumer<FieldResult>> temporalQuery(final ChronoField field) {
		return temporal -> result -> {
			if (field.isSupportedBy(temporal)) {
				String key = field.getBaseUnit().toString().toLowerCase();
				long value = field.getFrom(temporal);
				switch (field) {
					case YEAR:             result.years = value;break;
					case MONTH_OF_YEAR:    result.months = value;break;
					case DAY_OF_WEEK:      result.weekdays = value; key = "weekdays"; break;
					case DAY_OF_MONTH:     result.days = value;break;
					case HOUR_OF_DAY:      result.hours = value;break;
					case MINUTE_OF_HOUR:   result.minutes = value;break;
					case SECOND_OF_MINUTE: result.seconds = value;break;
				}
				result.value.put(key, value);
			}
		};
	}
}
package apoc.temporal;

import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.UserFunction;
import org.neo4j.values.storable.DurationValue;

import java.time.*;
import java.time.format.DateTimeFormatter;

import static apoc.date.Date.*;
import static apoc.util.DateFormatUtil.*;

public class TemporalProcedures
{
    /**
     * Format a temporal value to a String
     *
     * @param input     Any temporal type
     * @param format    A valid DateTime format pattern (ie yyyy-MM-dd'T'HH:mm:ss.SSSS)
     * @return
     */
    @UserFunction( "apoc.temporal.format" )
    @Description( "apoc.temporal.format(input, format) | Format a temporal value" )
    public String format(
            @Name( "temporal" ) Object input,
            @Name( value = "format", defaultValue = "yyyy-MM-dd") String format
    ) {

        try {
            DateTimeFormatter formatter = getOrCreate(format);

            if (input instanceof LocalDate) {
                return ((LocalDate) input).format(formatter);
            } else if (input instanceof ZonedDateTime) {
                return ((ZonedDateTime) input).format(formatter);
            } else if (input instanceof LocalDateTime) {
                return ((LocalDateTime) input).format(formatter);
            } else if (input instanceof LocalTime) {
                return ((LocalTime) input).format(formatter);
            } else if (input instanceof OffsetTime) {
                return ((OffsetTime) input).format(formatter);
            } else if (input instanceof DurationValue) {
                return formatDuration(input, format);
            }
        } catch (Exception e){
            throw new RuntimeException("Available formats are:\n" +
                    String.join("\n", getTypes()) +
                    "\nSee also: https://www.elastic.co/guide/en/elasticsearch/reference/5.5/mapping-date-format.html#built-in-date-formats " +
                    "and https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html");
        }
        return input.toString();
    }

    /**
     * Convert a Duration into a LocalTime and format the value as a String
     *
     * @param input
     * @param format
     * @return
     */
    @UserFunction( "apoc.temporal.formatDuration" )
    @Description( "apoc.temporal.formatDuration(input, format) | Format a Duration" )
    public String formatDuration(
            @Name("input") Object input,
            @Name("format") String format
    ) {
        try {
            LocalDateTime midnight = LocalDateTime.of(0, 1, 1, 0, 0, 0, 0);
            LocalDateTime newDuration = midnight.plus( (DurationValue) input );

            DateTimeFormatter formatter = getOrCreate(format);

            return newDuration.format(formatter);
        } catch (Exception e){
        throw new RuntimeException("Available formats are:\n" +
                String.join("\n", getTypes()) +
                "\nSee also: https://www.elastic.co/guide/en/elasticsearch/reference/5.5/mapping-date-format.html#built-in-date-formats " +
                "and https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html");
        }
    }

    @UserFunction
	@Description("apoc.temporal.toZonedTemporal('2012-12-23 23:59:59','yyyy-MM-dd HH:mm:ss', 'UTC-hour-offset') parse date string using the specified format to specified timezone")
	public ZonedDateTime toZonedTemporal(@Name("time") String time, @Name(value = "format", defaultValue = DEFAULT_FORMAT) String format, final @Name(value = "timezone", defaultValue = "UTC") String timezone) {
		Long value = parseOrThrow(time, getFormat(format, timezone));
		return value == null ? null : Instant.ofEpochMilli(value).atZone(ZoneId.of(timezone));
	}

}


http://www.kler.cn/news/362301.html

相关文章:

  • 数据治理(1)-数据规划
  • python基础知识汇总
  • 5G NR GSCN计算SSB中心频率MATLAB实现
  • 鸿蒙网络编程系列25-TCP回声服务器的实现
  • windows下Qt的安装方法
  • HTML作业
  • Android状态栏/通知栏图标白底问题
  • 归并排序 - 非递归实现
  • 代码随想录刷题Day8
  • 基于SSM汽车零部件加工系统的设计
  • bindService 流程学习总结
  • PTA L1系列题解(C语言)(L1_089 -- L1_096)
  • JZ2440开发板——MMU与Cache
  • 如何使用Git推送本地搭建的仓库以及远程克隆的仓库
  • golang中的上下文
  • 滚雪球学Redis[7.4讲]:Redis在分布式系统中的应用:微服务与跨数据中心策略
  • 016_基于python+django网络爬虫及数据分析可视化系统2024_kyz52ks2
  • Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题
  • python如何基于numpy pandas完成复杂的数据分析操作?
  • 华企盾对当前网络安全挑战与应对策略探讨
  • LeetCode102. 二叉树的层序遍历(2024秋季每日一题 43)
  • 毕业设计项目系统:基于Springboot框架的心理咨询评估管理系统,完整源代码+数据库+毕设文档+部署说明
  • python将1格式化为01
  • 思科网络设备命令
  • 9个用于测试自动化的最佳AI测试工具(2024)
  • NoSQL数据库分类简述