Skip to content

Commit ec6eb02

Browse files
plukasewern
authored andcommitted
[SAK-40018] increase precision of timestamps, and minor fixes to readme file
1 parent 3519fac commit ec6eb02

File tree

8 files changed

+90
-15
lines changed

8 files changed

+90
-15
lines changed

calendar/calendar-impl/impl/src/test/org/sakaiproject/calendar/impl/DbCalendarServiceSerializationTest.java

+10
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,16 @@ public String shortLocalizedTimestamp(Instant instant, Locale locale) {
456456
public String shortLocalizedDate(LocalDate date, Locale locale) {
457457
return null;
458458
}
459+
460+
@Override
461+
public String shortPreciseLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale) {
462+
return null;
463+
}
464+
465+
@Override
466+
public String shortPreciseLocalizedTimestamp(Instant instant, Locale locale) {
467+
return null;
468+
}
459469
};
460470
services = new HashMap<String,Object>();
461471
services.put("sqlservice", sqlService);

kernel/api/src/main/java/org/sakaiproject/time/api/UserTimeService.java

+23-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public interface UserTimeService {
4646

4747
/**
4848
* Formats a point in time, in the given time zone, for display to the user in a concise way that still presents all relevant information
49-
* including date, time, and time zone.
49+
* including date, time (to the minute), and time zone.
5050
*
5151
* @param instant the instant in time
5252
* @param timezone the time zone to use when displaying the date
@@ -55,15 +55,36 @@ public interface UserTimeService {
5555
*/
5656
public String shortLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale);
5757

58+
/**
59+
* Formats a point in time, in the given time zone, for display to the user in a concise way that still presents all relevant information
60+
* including date, time (to the second), and time zone.
61+
*
62+
* @param instant the instant in time
63+
* @param timezone the time zone to use when displaying the date
64+
* @param locale the locale to use when formatting the date for display
65+
* @return a formatted date/time for presentation to the user
66+
*/
67+
public String shortPreciseLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale);
68+
5869
/**
5970
* Formats a point in time, in the user's time zone, for display to the user in a concise way that still presents all relevant information
60-
* including date, time, and time zone.
71+
* including date, time (to the minute), and time zone.
6172
*
6273
* @param instant the instant in time
6374
* @param locale the locale to use when formatting the date for display
6475
* @return a formatted date/time for presentation to the user
6576
*/
77+
6678
public String shortLocalizedTimestamp(Instant instant, Locale locale);
79+
/**
80+
* Formats a point in time, in the user's time zone, for display to the user in a concise way that still presents all relevant information
81+
* including date, time (to the second), and time zone.
82+
*
83+
* @param instant the instant in time
84+
* @param locale the locale to use when formatting the date for display
85+
* @return a formatted date/time for presentation to the user
86+
*/
87+
public String shortPreciseLocalizedTimestamp(Instant instant, Locale locale);
6788

6889
/**
6990
* Formats a date (month/day/year) in a concise but easily understood format for the given locale.

kernel/kernel-impl/src/main/java/org/sakaiproject/content/impl/serialize/impl/conversion/ConversionTimeService.java

+10
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,14 @@ public String shortLocalizedTimestamp(Instant instant, Locale locale) {
213213
public String shortLocalizedDate(LocalDate date, Locale locale) {
214214
throw new UnsupportedOperationException("This class is only to be used for conversion purposes");
215215
}
216+
217+
@Override
218+
public String shortPreciseLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale) {
219+
throw new UnsupportedOperationException("This class is only to be used for conversion purposes");
220+
}
221+
222+
@Override
223+
public String shortPreciseLocalizedTimestamp(Instant instant, Locale locale) {
224+
throw new UnsupportedOperationException("This class is only to be used for conversion purposes");
225+
}
216226
}

kernel/kernel-impl/src/main/java/org/sakaiproject/time/impl/BasicTimeService.java

+10
Original file line numberDiff line numberDiff line change
@@ -1037,4 +1037,14 @@ public String shortLocalizedTimestamp(Instant instant, Locale locale) {
10371037
public String shortLocalizedDate(LocalDate date, Locale locale) {
10381038
return userTimeService.shortLocalizedDate(date, locale);
10391039
}
1040+
1041+
@Override
1042+
public String shortPreciseLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale) {
1043+
return userTimeService.shortPreciseLocalizedTimestamp(instant, timezone, locale);
1044+
}
1045+
1046+
@Override
1047+
public String shortPreciseLocalizedTimestamp(Instant instant, Locale locale) {
1048+
return userTimeService.shortPreciseLocalizedTimestamp(instant, getLocalTimeZone(), locale);
1049+
}
10401050
}

kernel/kernel-impl/src/main/java/org/sakaiproject/time/impl/UserTimeServiceImpl.java

+17-5
Original file line numberDiff line numberDiff line change
@@ -126,21 +126,33 @@ public String dateTimeFormatLong(Date date, Locale locale) {
126126
@Override
127127
public String shortLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale) {
128128
ZonedDateTime userDate = ZonedDateTime.ofInstant(instant, timezone.toZoneId());
129-
DateTimeFormatter userFormatter = new DateTimeFormatterBuilder()
130-
.appendLocalized(FormatStyle.MEDIUM, FormatStyle.SHORT)
131-
.appendLiteral(" ").appendZoneText(TextStyle.SHORT)
132-
.toFormatter(locale);
133-
return userDate.format(userFormatter);
129+
return userDate.format(buildTimestampFormatter(FormatStyle.MEDIUM, FormatStyle.SHORT, TextStyle.SHORT, locale));
134130
}
135131

136132
@Override
137133
public String shortLocalizedTimestamp(Instant instant, Locale locale) {
138134
return shortLocalizedTimestamp(instant, getLocalTimeZone(), locale);
139135
}
140136

137+
@Override
138+
public String shortPreciseLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale) {
139+
ZonedDateTime userDate = ZonedDateTime.ofInstant(instant, timezone.toZoneId());
140+
return userDate.format(buildTimestampFormatter(FormatStyle.MEDIUM, FormatStyle.MEDIUM, TextStyle.SHORT, locale));
141+
}
142+
143+
@Override
144+
public String shortPreciseLocalizedTimestamp(Instant instant, Locale locale) {
145+
return shortPreciseLocalizedTimestamp(instant, getLocalTimeZone(), locale);
146+
}
147+
141148
@Override
142149
public String shortLocalizedDate(LocalDate date, Locale locale) {
143150
DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(locale);
144151
return date.format(df);
145152
}
153+
154+
private DateTimeFormatter buildTimestampFormatter(FormatStyle dateStyle, FormatStyle timeStyle, TextStyle zoneStyle, Locale locale) {
155+
return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle)
156+
.appendLiteral(" ").appendZoneText(zoneStyle).toFormatter(locale);
157+
}
146158
}

kernel/kernel-impl/src/test/java/org/sakaiproject/content/impl/serialize/impl/test/MockTimeService.java

+10
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,14 @@ public String shortLocalizedTimestamp(Instant instant, Locale locale) {
232232
public String shortLocalizedDate(LocalDate date, Locale locale) {
233233
return null;
234234
}
235+
236+
@Override
237+
public String shortPreciseLocalizedTimestamp(Instant instant, TimeZone timezone, Locale locale) {
238+
return null;
239+
}
240+
241+
@Override
242+
public String shortPreciseLocalizedTimestamp(Instant instant, Locale locale) {
243+
return null;
244+
}
235245
}

sitestats/USER_ACTIVITY_README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Users should not be able to see information that they could not see in the tool'
8383
permissions and be aware of any special visibility restrictions in the tool. To that end:
8484

8585
* In cases where the tool's service layer does not include permission checks, additional permission checks are performed
86-
by User Activity. User Activity errs on the side of caution here and requires maintainer-levels permissions since it will
86+
by User Activity. User Activity errs on the side of caution here and requires maintainer-level permissions since it will
8787
grant access to details for any event from the tool. This is not the ideal scenario but is required for some tools.
8888
* User Activity is aware that several tools have a concept of anonymity, and tries to not reveal details that would
8989
compromise anonymity. For example, the details for an assignment submission event will not identify the assignment if
@@ -107,7 +107,7 @@ At a high level
107107

108108
* New Sakai events are recorded automatically by the Collection layer
109109
* Users invoke the Query layer to perform searches against these events by submitting the form on the User Activity page
110-
* Users may click the "show more" link for an individual event in the query results, invoking the Resolver layer
110+
* Users may click the "show more" button for an individual event in the query results, invoking the Resolver layer
111111
which uses Sakai services to get additional details about that particular event
112112
* The Presentation layer converts the specific details about the event into a form suitable for presentation
113113
back to the user, which is then displayed inline in the query results table.
@@ -172,7 +172,7 @@ ResolvedEventData objects representing error states can be returned instead of t
172172

173173
### Presentation layer
174174

175-
When presenting the details or a particular event to the user, the ResolvedEventData must be first be transformed into
175+
When presenting the details of a particular event to the user, the ResolvedEventData must be first be transformed into
176176
a presentable format.
177177

178178
Transformation, which includes localization, is done by a Transformer, of which there is one for each tool. For example,
@@ -183,18 +183,18 @@ EventDetail objects are simply localized key/value pairs. The value can be eithe
183183
a submission to a normal assignment called "Assignment 1" would be transformed into a single key/value pair of
184184
"Title"/"Assignment 1" (if user language was English). However, Transformers do more than simply localize each property
185185
of the ResolvedEventData. They contain logic that determines how to present the data. To continue the "Assignment 1"
186-
example, if the assignment has been deleted since the submission occurred, the Transformer would read both the "title"
186+
example, if the assignment has been deleted since the submission occurred, the Transformer would read both the "title" and
187187
"deleted" properties of the AssignmentEventData and present the value as "Assignment 1 \[deleted\]" (if the user language
188188
was English of course).
189189

190190
The current implementation uses a one-size-fits-all Wicket panel to present the list of EventDetail objects
191191
in the same way no matter which event they are for.
192192

193-
### Responsive Design
193+
#### Responsive Design
194194

195195
User Activity has a content-specific CSS breakpoint set at 640px that makes the following changes to the presentation:
196196

197197
- the search form switches to a column orientation
198-
- the table switches to a "CardTable" layout the presents each table row as a separate "card", allowing the user
198+
- the table switches to a "CardTable" layout that presents each table row as a separate "card", allowing the user
199199
to see all the data in the row at once even on a narrow device
200200

sitestats/sitestats-tool/src/java/org/sakaiproject/sitestats/tool/wicket/components/useractivity/UserTrackingResultsPanel.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
package org.sakaiproject.sitestats.tool.wicket.components.useractivity;
1717

18+
import java.time.Instant;
1819
import java.util.ArrayList;
1920
import java.util.List;
21+
import java.util.Locale;
2022

2123
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
2224
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
@@ -90,8 +92,8 @@ protected IModel createLabelModel(IModel rowModel)
9092
{
9193
// Get the event date
9294
DetailedEvent event = (DetailedEvent) rowModel.getObject();
93-
String dateStr = Locator.getFacade().getUserTimeService().shortLocalizedTimestamp(event.getEventDate().toInstant(), getSession().getLocale());
94-
return new Model<>(dateStr);
95+
Instant time = event.getEventDate().toInstant();
96+
return Model.of(Locator.getFacade().getUserTimeService().shortPreciseLocalizedTimestamp(time, getSession().getLocale()));
9597
}
9698
});
9799

0 commit comments

Comments
 (0)