Skip to content

Commit d4484ac

Browse files
authored
Merge pull request #15130 from codeconsole/7.0.x-gson-datecal-precision
gson views date/calendar should have millisecond precision to match standard rendering
2 parents 793dfde + 13655d9 commit d4484ac

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

grails-views-gson/src/main/groovy/grails/plugin/json/builder/JsonGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ interface Converter {
121121
*/
122122
class Options {
123123

124-
protected static final String JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
124+
protected static final String JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSX";
125125
protected static final Locale JSON_DATE_FORMAT_LOCALE = Locale.US;
126126
protected static final String DEFAULT_TIMEZONE = "GMT";
127127

grails-views-gson/src/main/groovy/grails/plugin/json/view/JsonViewGeneratorConfiguration.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class JsonViewGeneratorConfiguration {
2929

3030
Boolean escapeUnicode = false
3131

32-
String dateFormat = /yyyy-MM-dd'T'HH:mm:ss'Z'/
32+
String dateFormat = /yyyy-MM-dd'T'HH:mm:ss.SSSX/
3333

3434
String timeZone = 'GMT'
3535

grails-views-gson/src/test/groovy/grails/plugin/json/view/DateTimeRenderingSpec.groovy

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ json {
6262
createdInstant: instant
6363
])
6464

65-
then: "Date and Instant render with Z suffix"
66-
result.json.createdDate == "2025-10-07T21:14:31Z"
65+
then: "Date and Instant render with Z suffix and millisecond precision"
66+
result.json.createdDate == "2025-10-07T21:14:31.000Z"
6767
result.json.createdInstant == "2025-10-07T21:14:31Z"
6868

6969
and: "LocalDateTime renders without timezone (local time)"
@@ -194,4 +194,37 @@ json {
194194
result.json.date == "2025-10-08"
195195
result.json.date instanceof String
196196
}
197+
198+
void "Test Date and Calendar render with millisecond precision"() {
199+
given: "A view that renders Date and Calendar"
200+
String source = '''
201+
model {
202+
Date date
203+
Calendar calendar
204+
}
205+
206+
json {
207+
date date
208+
calendar calendar
209+
}
210+
'''
211+
212+
and: "Date and Calendar with millisecond precision"
213+
// Create a date with 407 milliseconds: 2025-10-08T07:48:46.407Z
214+
def calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"))
215+
calendar.set(2025, Calendar.OCTOBER, 8, 7, 48, 46)
216+
calendar.set(Calendar.MILLISECOND, 407)
217+
def date = calendar.getTime()
218+
219+
when: "The view is rendered"
220+
def result = render(source, [date: date, calendar: calendar])
221+
222+
then: "Date renders with millisecond precision"
223+
result.json.date == "2025-10-08T07:48:46.407Z"
224+
result.json.date instanceof String
225+
226+
and: "Calendar renders with millisecond precision"
227+
result.json.calendar == "2025-10-08T07:48:46.407Z"
228+
result.json.calendar instanceof String
229+
}
197230
}

0 commit comments

Comments
 (0)