View Javadoc
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 }