Отображение дат в часовом поясе пользователя

Отображение дат в часовом поясе пользователя

1. обзор

В этом выпускеthe Reddit app case study мы собираемся добавить bescheduling post’s according to the user’s timezone.

Работа с часовыми поясами общеизвестно трудна, а технические возможности широко открыты. Нашей первой заботой является то, что нам нужно показывать пользователю даты в соответствии с их собственным (настраиваемым) часовым поясом. Нам также нужно решитьwhat format the date will be saved as, in the database.

2. Предпочтение нового пользователя -timezone

Сначала мы добавим новое поле -timezone - к нашим уже существующим настройкам:

@Entity
public class Preference {
    ...
    private String timezone;
}

Затем мы простоmake the timezone configurable in the user Preferences Page - используя простой, но очень полезный JQueryplugin:


Обратите внимание, что часовой пояс по умолчанию - это часовой пояс сервера -which runs on UTC.

3. Контроллер

Теперь самое интересное. Нам нужно преобразовать даты изuser’s timezone вserver’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);
    }
}

Преобразование довольно простое, но обратите внимание, что оно происходит только при операциях записи - сервер по-прежнему возвращает UTC для чтения.

Это совершенно нормально для нашего клиента, потому что мы будем выполнять преобразование на JS, но это стоит понимать,for read operations, the server still returns UTC dates.

4. Фронтенд

А теперь давайте посмотрим, как использовать часовой пояс пользователя во внешнем интерфейсе:

4.1. Показать сообщения

Нам нужно будет отобразитьsubmissionDate сообщения с использованием часового пояса пользователя:

Post title Submission Date (UTC)

А вот наша функцияloadPage():

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 помогает здесь с преобразованием часового пояса.

4.2. Запланировать новую публикацию

Нам также нужно изменить нашschedulePostForm.html:

Submission Date (UTC)


Наконец, нам также нужно изменить нашeditPostForm.html, чтобы локализовать старое значениеsubmissonDate:

$(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. Заключение

В этой простой статье мы представили простую, но очень полезную функцию в приложении Reddit - возможность видеть все в соответствии с вашим часовым поясом.

Это былone of the main pain points as I was using the app - факт, что все было в формате UTC. Теперь - все даты правильно отображаются в часовом поясе пользователя, как и должно быть.