diff --git a/core/src/main/java/apoc/date/Date.java b/core/src/main/java/apoc/date/Date.java index 304c9f877..ec6d336c5 100644 --- a/core/src/main/java/apoc/date/Date.java +++ b/core/src/main/java/apoc/date/Date.java @@ -88,6 +88,31 @@ public double toYears( } @UserFunction("apoc.date.fields") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_5) + @Description("Splits the given date into fields returning a `MAP` containing the values of each field.") + public Map fieldsCypher5( + final @Name(value = "date", description = "A string representation of a temporal value.") String date, + final @Name( + value = "pattern", + defaultValue = DEFAULT_FORMAT, + description = "The format the given temporal is formatted as.") String pattern) { + if (date == null) { + return Util.map(); + } + DateTimeFormatter fmt = getSafeDateTimeFormatter(pattern); + TemporalAccessor temporal = fmt.parse(date); + FieldResult result = new FieldResult(); + + for (final TemporalQuery> query : DT_FIELDS_SELECTORS) { + query.queryFrom(temporal).accept(result); + } + + return result.asMap(); + } + + @Deprecated + @UserFunction(value = "apoc.date.fields", deprecatedBy = "Cypher's temporal pattern constructors.") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_25) @Description("Splits the given date into fields returning a `MAP` containing the values of each field.") public Map fields( final @Name(value = "date", description = "A string representation of a temporal value.") String date, @@ -278,6 +303,22 @@ public Long fromISO8601(final @Name(value = "time", description = "The datetime } @UserFunction("apoc.date.parse") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_5) + @Description("Parses the given date `STRING` from a specified format into the specified time unit.") + public Long parseCypher5( + @Name(value = "time", description = "The datetime to convert.") String time, + @Name(value = "unit", defaultValue = "ms", description = "The conversion unit.") String unit, + @Name(value = "format", defaultValue = DEFAULT_FORMAT, description = "The format the given datetime is in.") + String format, + final @Name(value = "timezone", defaultValue = "", description = "The timezone the given datetime is in.") + String timezone) { + Long value = StringUtils.isBlank(time) ? null : parseOrThrow(time, getFormat(format, timezone)); + return value == null ? null : unit(unit).convert(value, TimeUnit.MILLISECONDS); + } + + @Deprecated + @UserFunction(value = "apoc.date.parse", deprecatedBy = "Cypher's temporal pattern constructors.") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_25) @Description("Parses the given date `STRING` from a specified format into the specified time unit.") public Long parse( @Name(value = "time", description = "The datetime to convert.") String time, @@ -306,6 +347,32 @@ public Long convert( } @UserFunction("apoc.date.convertFormat") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_5) + @Description("Converts a `STRING` of one type of date format into a `STRING` of another type of date format.") + public String convertFormatCypher5( + @Name(value = "temporal", description = "A string representation of a temporal value.") String input, + @Name(value = "currentFormat", description = "The format the given temporal is formatted as.") + String currentFormat, + @Name( + value = "convertTo", + defaultValue = "yyyy-MM-dd", + description = "The format to convert the given temporal value to.") + 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)); + } + + @Deprecated + @UserFunction( + value = "apoc.date.convertFormat", + deprecatedBy = "Cypher's temporal pattern constructors and format() function.") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_25) @Description("Converts a `STRING` of one type of date format into a `STRING` of another type of date format.") public String convertFormat( @Name(value = "temporal", description = "A string representation of a temporal value.") String input, diff --git a/core/src/main/java/apoc/temporal/TemporalProcedures.java b/core/src/main/java/apoc/temporal/TemporalProcedures.java index 654ab0629..ecd791672 100644 --- a/core/src/main/java/apoc/temporal/TemporalProcedures.java +++ b/core/src/main/java/apoc/temporal/TemporalProcedures.java @@ -157,6 +157,21 @@ public String formatDuration( } @UserFunction("apoc.temporal.toZonedTemporal") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_5) + @Description("Parses the given date `STRING` using the specified format into the given time zone.") + public ZonedDateTime toZonedTemporalCypher5( + @Name(value = "time", description = "The date string to be parsed.") String time, + @Name(value = "format", defaultValue = DEFAULT_FORMAT, description = "The format of the given date string.") + String format, + final @Name(value = "timezone", defaultValue = "UTC", description = "The timezone the given string is in.") + String timezone) { + Long value = parseOrThrow(time, getFormat(format, timezone)); + return value == null ? null : Instant.ofEpochMilli(value).atZone(ZoneId.of(timezone)); + } + + @Deprecated + @UserFunction(value = "apoc.temporal.toZonedTemporal", deprecatedBy = "Cypher's temporal pattern constructors.") + @QueryLanguageScope(scope = QueryLanguage.CYPHER_25) @Description("Parses the given date `STRING` using the specified format into the given time zone.") public ZonedDateTime toZonedTemporal( @Name(value = "time", description = "The date string to be parsed.") String time, diff --git a/core/src/test/resources/functions/common/functions.json b/core/src/test/resources/functions/common/functions.json index 47ca24c64..77d0d2ced 100644 --- a/core/src/test/resources/functions/common/functions.json +++ b/core/src/test/resources/functions/common/functions.json @@ -1675,104 +1675,6 @@ } ] }, - { - "isDeprecated": false, - "aggregating": false, - "signature": "apoc.date.convertFormat(temporal :: STRING, currentFormat :: STRING, convertTo = yyyy-MM-dd :: STRING) :: STRING", - "name": "apoc.date.convertFormat", - "description": "Converts a `STRING` of one type of date format into a `STRING` of another type of date format.", - "returnDescription": "STRING", - "deprecatedBy": null, - "category": "", - "isBuiltIn": false, - "argumentDescription": [ - { - "name": "temporal", - "description": "A string representation of a temporal value.", - "isDeprecated": false, - "type": "STRING" - }, - { - "name": "currentFormat", - "description": "The format the given temporal is formatted as.", - "isDeprecated": false, - "type": "STRING" - }, - { - "name": "convertTo", - "description": "The format to convert the given temporal value to.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=yyyy-MM-dd, type=STRING}", - "type": "STRING" - } - ] - }, - { - "isDeprecated": false, - "aggregating": false, - "signature": "apoc.date.fields(date :: STRING, pattern = yyyy-MM-dd HH:mm:ss :: STRING) :: MAP", - "name": "apoc.date.fields", - "description": "Splits the given date into fields returning a `MAP` containing the values of each field.", - "returnDescription": "MAP", - "deprecatedBy": null, - "category": "", - "isBuiltIn": false, - "argumentDescription": [ - { - "name": "date", - "description": "A string representation of a temporal value.", - "isDeprecated": false, - "type": "STRING" - }, - { - "name": "pattern", - "description": "The format the given temporal is formatted as.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", - "type": "STRING" - } - ] - }, - { - "isDeprecated": false, - "aggregating": false, - "signature": "apoc.date.parse(time :: STRING, unit = ms :: STRING, format = yyyy-MM-dd HH:mm:ss :: STRING, timezone = :: STRING) :: INTEGER", - "name": "apoc.date.parse", - "description": "Parses the given date `STRING` from a specified format into the specified time unit.", - "returnDescription": "INTEGER", - "deprecatedBy": null, - "category": "", - "isBuiltIn": false, - "argumentDescription": [ - { - "name": "time", - "description": "The datetime to convert.", - "isDeprecated": false, - "type": "STRING" - }, - { - "name": "unit", - "description": "The conversion unit.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=ms, type=STRING}", - "type": "STRING" - }, - { - "name": "format", - "description": "The format the given datetime is in.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", - "type": "STRING" - }, - { - "name": "timezone", - "description": "The timezone the given datetime is in.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=, type=STRING}", - "type": "STRING" - } - ] - }, { "isDeprecated": false, "aggregating": false, @@ -3716,39 +3618,6 @@ } ] }, - { - "isDeprecated": false, - "aggregating": false, - "signature": "apoc.temporal.toZonedTemporal(time :: STRING, format = yyyy-MM-dd HH:mm:ss :: STRING, timezone = UTC :: STRING) :: ZONED DATETIME", - "name": "apoc.temporal.toZonedTemporal", - "description": "Parses the given date `STRING` using the specified format into the given time zone.", - "returnDescription": "ZONED DATETIME", - "deprecatedBy": null, - "category": "", - "isBuiltIn": false, - "argumentDescription": [ - { - "name": "time", - "description": "The date string to be parsed.", - "isDeprecated": false, - "type": "STRING" - }, - { - "name": "format", - "description": "The format of the given date string.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", - "type": "STRING" - }, - { - "name": "timezone", - "description": "The timezone the given string is in.", - "isDeprecated": false, - "default": "DefaultParameterValue{value=UTC, type=STRING}", - "type": "STRING" - } - ] - }, { "isDeprecated": false, "aggregating": false, diff --git a/core/src/test/resources/functions/cypher25/functions.json b/core/src/test/resources/functions/cypher25/functions.json index a0583ee04..f5a306dd6 100644 --- a/core/src/test/resources/functions/cypher25/functions.json +++ b/core/src/test/resources/functions/cypher25/functions.json @@ -440,6 +440,38 @@ } ] }, + { + "isDeprecated": true, + "aggregating": false, + "signature": "apoc.date.convertFormat(temporal :: STRING, currentFormat :: STRING, convertTo = yyyy-MM-dd :: STRING) :: STRING", + "name": "apoc.date.convertFormat", + "description": "Converts a `STRING` of one type of date format into a `STRING` of another type of date format.", + "returnDescription": "STRING", + "deprecatedBy": "Cypher's temporal pattern constructors and format() function.", + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "temporal", + "description": "A string representation of a temporal value.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "currentFormat", + "description": "The format the given temporal is formatted as.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "convertTo", + "description": "The format to convert the given temporal value to.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": true, "aggregating": false, @@ -485,6 +517,32 @@ } ] }, + { + "isDeprecated": true, + "aggregating": false, + "signature": "apoc.date.fields(date :: STRING, pattern = yyyy-MM-dd HH:mm:ss :: STRING) :: MAP", + "name": "apoc.date.fields", + "description": "Splits the given date into fields returning a `MAP` containing the values of each field.", + "returnDescription": "MAP", + "deprecatedBy": "Cypher's temporal pattern constructors.", + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "date", + "description": "A string representation of a temporal value.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "pattern", + "description": "The format the given temporal is formatted as.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": true, "aggregating": false, @@ -544,6 +602,46 @@ } ] }, + { + "isDeprecated": true, + "aggregating": false, + "signature": "apoc.date.parse(time :: STRING, unit = ms :: STRING, format = yyyy-MM-dd HH:mm:ss :: STRING, timezone = :: STRING) :: INTEGER", + "name": "apoc.date.parse", + "description": "Parses the given date `STRING` from a specified format into the specified time unit.", + "returnDescription": "INTEGER", + "deprecatedBy": "Cypher's temporal pattern constructors.", + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "time", + "description": "The datetime to convert.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "unit", + "description": "The conversion unit.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=ms, type=STRING}", + "type": "STRING" + }, + { + "name": "format", + "description": "The format the given datetime is in.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", + "type": "STRING" + }, + { + "name": "timezone", + "description": "The timezone the given datetime is in.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": true, "aggregating": false, @@ -844,5 +942,38 @@ "type": "STRING" } ] + }, + { + "isDeprecated": true, + "aggregating": false, + "signature": "apoc.temporal.toZonedTemporal(time :: STRING, format = yyyy-MM-dd HH:mm:ss :: STRING, timezone = UTC :: STRING) :: ZONED DATETIME", + "name": "apoc.temporal.toZonedTemporal", + "description": "Parses the given date `STRING` using the specified format into the given time zone.", + "returnDescription": "ZONED DATETIME", + "deprecatedBy": "Cypher's temporal pattern constructors.", + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "time", + "description": "The date string to be parsed.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "format", + "description": "The format of the given date string.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", + "type": "STRING" + }, + { + "name": "timezone", + "description": "The timezone the given string is in.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=UTC, type=STRING}", + "type": "STRING" + } + ] } ] \ No newline at end of file diff --git a/core/src/test/resources/functions/cypher5/functions.json b/core/src/test/resources/functions/cypher5/functions.json index 37e74e3a7..413010008 100644 --- a/core/src/test/resources/functions/cypher5/functions.json +++ b/core/src/test/resources/functions/cypher5/functions.json @@ -452,6 +452,38 @@ "isBuiltIn": false, "argumentDescription": [] }, + { + "isDeprecated": false, + "aggregating": false, + "signature": "apoc.date.convertFormat(temporal :: STRING, currentFormat :: STRING, convertTo = yyyy-MM-dd :: STRING) :: STRING", + "name": "apoc.date.convertFormat", + "description": "Converts a `STRING` of one type of date format into a `STRING` of another type of date format.", + "returnDescription": "STRING", + "deprecatedBy": null, + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "temporal", + "description": "A string representation of a temporal value.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "currentFormat", + "description": "The format the given temporal is formatted as.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "convertTo", + "description": "The format to convert the given temporal value to.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": false, "aggregating": false, @@ -497,6 +529,32 @@ } ] }, + { + "isDeprecated": false, + "aggregating": false, + "signature": "apoc.date.fields(date :: STRING, pattern = yyyy-MM-dd HH:mm:ss :: STRING) :: MAP", + "name": "apoc.date.fields", + "description": "Splits the given date into fields returning a `MAP` containing the values of each field.", + "returnDescription": "MAP", + "deprecatedBy": null, + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "date", + "description": "A string representation of a temporal value.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "pattern", + "description": "The format the given temporal is formatted as.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": false, "aggregating": false, @@ -556,6 +614,46 @@ } ] }, + { + "isDeprecated": false, + "aggregating": false, + "signature": "apoc.date.parse(time :: STRING, unit = ms :: STRING, format = yyyy-MM-dd HH:mm:ss :: STRING, timezone = :: STRING) :: INTEGER", + "name": "apoc.date.parse", + "description": "Parses the given date `STRING` from a specified format into the specified time unit.", + "returnDescription": "INTEGER", + "deprecatedBy": null, + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "time", + "description": "The datetime to convert.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "unit", + "description": "The conversion unit.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=ms, type=STRING}", + "type": "STRING" + }, + { + "name": "format", + "description": "The format the given datetime is in.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", + "type": "STRING" + }, + { + "name": "timezone", + "description": "The timezone the given datetime is in.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": false, "aggregating": false, @@ -888,6 +986,39 @@ } ] }, + { + "isDeprecated": false, + "aggregating": false, + "signature": "apoc.temporal.toZonedTemporal(time :: STRING, format = yyyy-MM-dd HH:mm:ss :: STRING, timezone = UTC :: STRING) :: ZONED DATETIME", + "name": "apoc.temporal.toZonedTemporal", + "description": "Parses the given date `STRING` using the specified format into the given time zone.", + "returnDescription": "ZONED DATETIME", + "deprecatedBy": null, + "category": "", + "isBuiltIn": false, + "argumentDescription": [ + { + "name": "time", + "description": "The date string to be parsed.", + "isDeprecated": false, + "type": "STRING" + }, + { + "name": "format", + "description": "The format of the given date string.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=yyyy-MM-dd HH:mm:ss, type=STRING}", + "type": "STRING" + }, + { + "name": "timezone", + "description": "The timezone the given string is in.", + "isDeprecated": false, + "default": "DefaultParameterValue{value=UTC, type=STRING}", + "type": "STRING" + } + ] + }, { "isDeprecated": true, "aggregating": false,