1概要
今回のリンク:/case-study-a-reddit-app-with-Spring[Reddit appのケーススタディ]では、ユーザーのタイムゾーンに応じてbe ** スケジューリング投稿を追加します。
タイムゾーンを扱うことは非常に困難であり、技術的な選択肢は広く開かれています。私たちの最初の関心事は、我々が彼ら自身の(設定可能な)タイムゾーンに従ってユーザーに日付を示す必要があるということです。私たちはまた、日付をデータベースに保存する形式を決める必要があります。
** 2新しいユーザー設定 - timezone
**
まず、既存の設定に timezone という新しいフィールドを追加します。
@Entity
public class Preference {
...
private String timezone;
}
それから ユーザーの設定ページで タイムゾーンを設定可能にする** - シンプルだが非常に便利なJQueryを活用しています。 Timezones.html[プラグイン]:
<select id="timezone" name="timezone"></select>
<script>
$(function() {
$('#timezone').timezones();
});
</script>
デフォルトのタイムゾーンは、 UTC 。 で実行されるサーバータイムゾーン - です。
3コントローラー
さて、楽しみの部分のために。日付を ユーザーのタイムゾーン から サーバーのタイムゾーン に変換する必要があります。
@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で変換を行うので、クライアントにとってはこれで十分です。ただし、読み取り操作の場合、サーバーは依然としてUTCの日付を返します。
** 4フロントエンド
**
では、フロントエンドでユーザーのタイムゾーンを使用する方法を見てみましょう。
4.1. 投稿を表示する
ユーザーのタイムゾーンを使用して投稿の submissionDate を表示する必要があります。
<table><thead><tr>
<th>Post title</th>
<th>Submission Date
(<span id="timezone" sec:authentication="principal.preference.timezone">UTC</span>)</th>
</tr></thead></table>
そして、これが私たちの関数 loadPage() です:
function loadPage(page){
...
$('.table').append('<tr><td>'+post.title+'</td><td>'+
convertDate(post.submissionDate)+'</td></tr>');
...
}
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 (<span sec:authentication="principal.preference.timezone">UTC</span>)
<input id="date" name="date"/>
<script type="text/javascript">
function schedulePost(){
var data = {};
$('form').serializeArray().map(function(x){data[x.name]= x.value;});
$.ajax({
url: 'api/scheduledPosts?date='+$("#date").val(),
data: JSON.stringify(data),
type: 'POST',
contentType:'application/json',
success: function(result) {
window.location.href="scheduledPosts";
},
error: function(error) {
alert(error.responseText);
}
});
}
</script>
最後に - subitsonDate の古い値をローカライズするために editPostForm.html を変更する必要があります。
$(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アプリにシンプルだが非常に便利な機能、つまり自分のタイムゾーンに従ってすべてを表示する機能を紹介しました。
これは、私がこのアプリを使用していたときの主な問題点の1つでした。今 - すべての日付は、それらがあるべきであるように、ユーザーのタイムゾーンに正しく表示されます。