Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
value = "Formats a date object",
params = {
@JinjavaParam(value = "value", defaultValue = "current time", desc = "The date variable or UNIX timestamp to format"),
@JinjavaParam(value = "format", defaultValue = StrftimeFormatter.DEFAULT_DATE_FORMAT, desc = "The format of the date determined by the directives added to this parameter")
@JinjavaParam(value = "format", defaultValue = StrftimeFormatter.DEFAULT_DATE_FORMAT, desc = "The format of the date determined by the directives added to this parameter"),
@JinjavaParam(value = "timezone", defaultValue = "utc", desc = "Time zone of output date")
},
snippets = {
@JinjavaSnippet(code = "{% content.updated|datetimeformat('%B %e, %Y') %}"),
Expand All @@ -29,12 +30,11 @@ public Object filter(Object var, JinjavaInterpreter interpreter,
String... args) {

if (args.length > 0) {
return Functions.dateTimeFormat(var, args[0]);
return Functions.dateTimeFormat(var, args);
}
else {
return Functions.dateTimeFormat(var);
}

}

}
37 changes: 30 additions & 7 deletions src/main/java/com/hubspot/jinjava/lib/fn/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import static com.hubspot.jinjava.util.Logging.ENGINE_LOG;

import java.time.DateTimeException;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
Expand All @@ -21,6 +23,7 @@
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.InterpretException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.objects.date.InvalidDateFormatException;
import com.hubspot.jinjava.objects.date.PyishDate;
import com.hubspot.jinjava.objects.date.StrftimeFormatter;
import com.hubspot.jinjava.tree.Node;
Expand Down Expand Up @@ -57,10 +60,27 @@ public static List<Object> immutableListOf(Object... items) {

@JinjavaDoc(value = "formats a date to a string", params = {
@JinjavaParam(value = "var", type = "date", defaultValue = "current time"),
@JinjavaParam(value = "format", defaultValue = StrftimeFormatter.DEFAULT_DATE_FORMAT)
@JinjavaParam(value = "format", defaultValue = StrftimeFormatter.DEFAULT_DATE_FORMAT),
@JinjavaParam(value = "timezone", defaultValue = "utc", desc = "Time zone of output date")
})
public static String dateTimeFormat(Object var, String... format) {
ZonedDateTime d = getDateTimeArg(var);

ZoneId zoneOffset = ZoneOffset.UTC;

if (format.length > 1) {
String timezone = format[1];
try {
zoneOffset = ZoneId.of(timezone);
} catch (DateTimeException e) {
throw new InvalidDateFormatException(timezone, e);
}
} else if (var instanceof ZonedDateTime) {
zoneOffset = ((ZonedDateTime) var).getZone();
} else if (var instanceof PyishDate) {
zoneOffset = ((PyishDate) var).toDateTime().getZone();
}

ZonedDateTime d = getDateTimeArg(var, zoneOffset);

if (d == null) {
return "";
Expand All @@ -78,18 +98,21 @@ public static String dateTimeFormat(Object var, String... format) {
}
}

private static ZonedDateTime getDateTimeArg(Object var) {
private static ZonedDateTime getDateTimeArg(Object var, ZoneId zoneOffset) {

ZonedDateTime d = null;

if (var == null) {
d = ZonedDateTime.now(ZoneOffset.UTC);
d = ZonedDateTime.now(zoneOffset);
} else if (var instanceof Number) {
d = ZonedDateTime.ofInstant(Instant.ofEpochMilli(((Number) var).longValue()), ZoneOffset.UTC);
d = ZonedDateTime.ofInstant(Instant.ofEpochMilli(((Number) var).longValue()), zoneOffset);
} else if (var instanceof PyishDate) {
d = ((PyishDate) var).toDateTime();
PyishDate pyishDate = ((PyishDate) var);
d = pyishDate.toDateTime();
d = d.withZoneSameInstant(zoneOffset);
} else if (var instanceof ZonedDateTime) {
d = (ZonedDateTime) var;
d = d.withZoneSameInstant(zoneOffset);
} else if (!ZonedDateTime.class.isAssignableFrom(var.getClass())) {
throw new InterpretException("Input to function must be a date object, was: " + var.getClass());
}
Expand All @@ -101,7 +124,7 @@ private static ZonedDateTime getDateTimeArg(Object var) {
@JinjavaParam(value = "var", type = "date", defaultValue = "current time"),
})
public static long unixtimestamp(Object var) {
ZonedDateTime d = getDateTimeArg(var);
ZonedDateTime d = getDateTimeArg(var, ZoneOffset.UTC);

if (d == null) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.hubspot.jinjava.Jinjava;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.objects.date.InvalidDateFormatException;
import com.hubspot.jinjava.objects.date.StrftimeFormatter;

public class DateTimeFormatFilterTest {
Expand Down Expand Up @@ -58,4 +59,20 @@ public void itHandlesVarsAndLiterals() throws Exception {
assertThat(interpreter.getErrorsCopy()).isEmpty();
}

@Test
public void itSupportsTimezones() throws Exception {
assertThat(filter.filter(1539277785000L, interpreter, "%B %d, %Y, at %I:%M %p")).isEqualTo("October 11, 2018, at 05:09 PM");
assertThat(filter.filter(1539277785000L, interpreter, "%B %d, %Y, at %I:%M %p", "America/New_York")).isEqualTo("October 11, 2018, at 01:09 PM");
assertThat(filter.filter(1539277785000L, interpreter, "%B %d, %Y, at %I:%M %p", "UTC+8")).isEqualTo("October 12, 2018, at 01:09 AM");
}

@Test(expected = InvalidDateFormatException.class)
public void itThrowsExceptionOnInvalidTimezone() throws Exception {
filter.filter(1539277785000L, interpreter, "%B %d, %Y, at %I:%M %p", "Not a timezone");
}

@Test(expected = InvalidDateFormatException.class)
public void itThrowsExceptionOnInvalidDateformat() throws Exception {
filter.filter(1539277785000L, interpreter, "Not a format");
}
}