1 /*
2 * Copyright (C) 2011, 2012 Robin Rosenberg
3 * and other copyright owners as documented in the project's IP log.
4 *
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 package org.eclipse.jgit.util;
45
46 import java.text.DateFormat;
47 import java.text.SimpleDateFormat;
48 import java.util.Locale;
49 import java.util.TimeZone;
50
51 import org.eclipse.jgit.lib.PersonIdent;
52
53 /**
54 * A utility for formatting dates according to the Git log.date formats plus
55 * extensions.
56 * <p>
57 * The enum {@link org.eclipse.jgit.util.GitDateFormatter.Format} defines the
58 * available types.
59 */
60 public class GitDateFormatter {
61
62 private DateFormat dateTimeInstance;
63
64 private DateFormat dateTimeInstance2;
65
66 private final Format format;
67
68 /**
69 * Git and JGit formats
70 */
71 static public enum Format {
72
73 /**
74 * Git format: Time and original time zone
75 */
76 DEFAULT,
77
78 /**
79 * Git format: Relative time stamp
80 */
81 RELATIVE,
82
83 /**
84 * Git format: Date and time in local time zone
85 */
86 LOCAL,
87
88 /**
89 * Git format: ISO 8601 plus time zone
90 */
91 ISO,
92
93 /**
94 * Git formt: RFC 2822 plus time zone
95 */
96 RFC,
97
98 /**
99 * Git format: YYYY-MM-DD
100 */
101 SHORT,
102
103 /**
104 * Git format: Seconds size 1970 in UTC plus time zone
105 */
106 RAW,
107
108 /**
109 * Locale dependent formatting with original time zone
110 */
111 LOCALE,
112
113 /**
114 * Locale dependent formatting in local time zone
115 */
116 LOCALELOCAL
117 }
118
119 /**
120 * Create a new Git oriented date formatter
121 *
122 * @param format
123 * a {@link org.eclipse.jgit.util.GitDateFormatter.Format}
124 * object.
125 */
126 public GitDateFormatter(Format format) {
127 this.format = format;
128 switch (format) {
129 default:
130 break;
131 case DEFAULT: // Not default:
132 dateTimeInstance = new SimpleDateFormat(
133 "EEE MMM dd HH:mm:ss yyyy Z", Locale.US); //$NON-NLS-1$
134 break;
135 case ISO:
136 dateTimeInstance = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", //$NON-NLS-1$
137 Locale.US);
138 break;
139 case LOCAL:
140 dateTimeInstance = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy", //$NON-NLS-1$
141 Locale.US);
142 break;
143 case RFC:
144 dateTimeInstance = new SimpleDateFormat(
145 "EEE, dd MMM yyyy HH:mm:ss Z", Locale.US); //$NON-NLS-1$
146 break;
147 case SHORT:
148 dateTimeInstance = new SimpleDateFormat("yyyy-MM-dd", Locale.US); //$NON-NLS-1$
149 break;
150 case LOCALE:
151 case LOCALELOCAL:
152 SystemReader systemReader = SystemReader.getInstance();
153 dateTimeInstance = systemReader.getDateTimeInstance(
154 DateFormat.DEFAULT, DateFormat.DEFAULT);
155 dateTimeInstance2 = systemReader.getSimpleDateFormat("Z"); //$NON-NLS-1$
156 break;
157 }
158 }
159
160 /**
161 * Format committer, author or tagger ident according to this formatter's
162 * specification.
163 *
164 * @param ident
165 * a {@link org.eclipse.jgit.lib.PersonIdent} object.
166 * @return formatted version of date, time and time zone
167 */
168 @SuppressWarnings("boxing")
169 public String formatDate(PersonIdent ident) {
170 switch (format) {
171 case RAW:
172 int offset = ident.getTimeZoneOffset();
173 String sign = offset < 0 ? "-" : "+"; //$NON-NLS-1$ //$NON-NLS-2$
174 int offset2;
175 if (offset < 0)
176 offset2 = -offset;
177 else
178 offset2 = offset;
179 int hours = offset2 / 60;
180 int minutes = offset2 % 60;
181 return String.format("%d %s%02d%02d", //$NON-NLS-1$
182 ident.getWhen().getTime() / 1000, sign, hours, minutes);
183 case RELATIVE:
184 return RelativeDateFormatter.format(ident.getWhen());
185 case LOCALELOCAL:
186 case LOCAL:
187 dateTimeInstance.setTimeZone(SystemReader.getInstance()
188 .getTimeZone());
189 return dateTimeInstance.format(ident.getWhen());
190 case LOCALE:
191 TimeZone tz = ident.getTimeZone();
192 if (tz == null)
193 tz = SystemReader.getInstance().getTimeZone();
194 dateTimeInstance.setTimeZone(tz);
195 dateTimeInstance2.setTimeZone(tz);
196 return dateTimeInstance.format(ident.getWhen()) + " " //$NON-NLS-1$
197 + dateTimeInstance2.format(ident.getWhen());
198 default:
199 tz = ident.getTimeZone();
200 if (tz == null)
201 tz = SystemReader.getInstance().getTimeZone();
202 dateTimeInstance.setTimeZone(ident.getTimeZone());
203 return dateTimeInstance.format(ident.getWhen());
204 }
205 }
206 }