Exibindo datas no fuso horário do usuário
1. Visão geral
Nesta parcela dethe Reddit app case study, vamos adicionar o bescheduling post’s according to the user’s timezone.
Lidar com fusos horários é notoriamente difícil e as opções técnicas estão amplamente abertas. Nossa primeira preocupação é que precisamos mostrar as datas para o usuário de acordo com seu próprio fuso horário (configurável). Também precisamos decidirwhat format the date will be saved as, in the database.
2. Uma preferência de novo usuário -timezone
Primeiro, vamos adicionar um novo campo -timezone - às nossas preferências já existentes:
@Entity
public class Preference {
...
private String timezone;
}
Em seguida, simplesmentemake the timezone configurable in the user Preferences Page - aproveitando um JQueryplugin simples, mas muito útil:
Observe que o fuso horário padrão é o fuso horário do servidor -which runs on UTC.
3. O controlador
Agora a parte divertida. Precisamos converter as datas deuser’s timezone paraserver’s timezone:
@Controller
@RequestMapping(value = "/api/scheduledPosts")
public class ScheduledPostRestController {
private static final SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm");
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public void schedule(
@RequestBody Post post,
@RequestParam(value = "date") String date) throws ParseException
{
post.setSubmissionDate(
calculateSubmissionDate(date, getCurrentUser().getPreference().getTimezone()));
...
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.OK)
public void updatePost(
@RequestBody Post post,
@RequestParam(value = "date") String date) throws ParseException
{
post.setSubmissionDate(
calculateSubmissionDate(date, getCurrentUser().getPreference().getTimezone()));
...
}
private synchronized Date calculateSubmissionDate(String dateString, String userTimeZone)
throws ParseException {
dateFormat.setTimeZone(TimeZone.getTimeZone(userTimeZone));
return dateFormat.parse(dateString);
}
}
A conversão é bastante direta, mas observe que ela só está acontecendo em operações de gravação - o servidor ainda retorna UTC para leituras.
Isso é perfeitamente adequado para nosso cliente, porque faremos a conversão em JS - mas vale a pena entender que,for read operations, the server still returns UTC dates
4. O Front-End
Agora - vamos ver como usar o fuso horário do usuário no front-end:
4.1. Exibir as postagens
Precisaremos exibir osubmissionDate da postagem usando o fuso horário do usuário:
Post title
Submission Date
(UTC)
E aqui está nossa funçãoloadPage():
function loadPage(page){
...
$('.table').append(''+post.title+' '+
convertDate(post.submissionDate)+' ');
...
}
function convertDate(date){
var serverTimezone = [[dates.format(#calendars.createToday(), 'z')}]];
var serverDate = moment.tz(date, serverTimezone);
var clientDate = serverDate.clone().tz($("#timezone").html());
var myformat = "YYYY-MM-DD HH:mm";
return clientDate.format(myformat);
}
Moment.js ajuda aqui com a conversão de fuso horário.
4.2. Agende uma nova postagem
Também precisamos modificar nossoschedulePostForm.html:
Submission Date (UTC)
Finalmente - também precisamos modificar nossoeditPostForm.html para localizar o valor antigo desubmissonDate:
$(function() {
var serverTimezone = [[dates.format(#calendars.createToday(), 'z')}]];
var serverDate = moment.tz($("#date").val(), serverTimezone);
var clientDate = serverDate.clone().tz($("#timezone").html());
var myformat = "YYYY-MM-DD HH:mm";
$("#date").val(clientDate.format(myformat));
});
5. Conclusão
Neste artigo simples, introduzimos um recurso simples, mas altamente útil, no aplicativo Reddit - a capacidade de ver tudo de acordo com seu próprio fuso horário.
Eraone of the main pain points as I was using the app - o fato de que tudo estava em UTC. Agora - todas as datas são exibidas corretamente no fuso horário do usuário, como deveriam.