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 Format} defines the available types.
58   */
59  public class GitDateFormatter {
60  
61  	private DateFormat dateTimeInstance;
62  
63  	private DateFormat dateTimeInstance2;
64  
65  	private final Format format;
66  
67  	/**
68  	 * Git and JGit formats
69  	 */
70  	static public enum Format {
71  
72  		/**
73  		 * Git format: Time and original time zone
74  		 */
75  		DEFAULT,
76  
77  		/**
78  		 * Git format: Relative time stamp
79  		 */
80  		RELATIVE,
81  
82  		/**
83  		 * Git format: Date and time in local time zone
84  		 */
85  		LOCAL,
86  
87  		/**
88  		 * Git format: ISO 8601 plus time zone
89  		 */
90  		ISO,
91  
92  		/**
93  		 * Git formt: RFC 2822 plus time zone
94  		 */
95  		RFC,
96  
97  		/**
98  		 * Git format: YYYY-MM-DD
99  		 */
100 		SHORT,
101 
102 		/**
103 		 * Git format: Seconds size 1970 in UTC plus time zone
104 		 */
105 		RAW,
106 
107 		/**
108 		 * Locale dependent formatting with original time zone
109 		 */
110 		LOCALE,
111 
112 		/**
113 		 * Locale dependent formatting in local time zone
114 		 */
115 		LOCALELOCAL
116 	}
117 
118 	/**
119 	 * Create a new Git oriented date formatter
120 	 *
121 	 * @param format
122 	 */
123 	public GitDateFormatter(Format format) {
124 		this.format = format;
125 		switch (format) {
126 		default:
127 			break;
128 		case DEFAULT: // Not default:
129 			dateTimeInstance = new SimpleDateFormat(
130 					"EEE MMM dd HH:mm:ss yyyy Z", Locale.US); //$NON-NLS-1$
131 			break;
132 		case ISO:
133 			dateTimeInstance = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", //$NON-NLS-1$
134 					Locale.US);
135 			break;
136 		case LOCAL:
137 			dateTimeInstance = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy", //$NON-NLS-1$
138 					Locale.US);
139 			break;
140 		case RFC:
141 			dateTimeInstance = new SimpleDateFormat(
142 					"EEE, dd MMM yyyy HH:mm:ss Z", Locale.US); //$NON-NLS-1$
143 			break;
144 		case SHORT:
145 			dateTimeInstance = new SimpleDateFormat("yyyy-MM-dd", Locale.US); //$NON-NLS-1$
146 			break;
147 		case LOCALE:
148 		case LOCALELOCAL:
149 			SystemReader systemReader = SystemReader.getInstance();
150 			dateTimeInstance = systemReader.getDateTimeInstance(
151 					DateFormat.DEFAULT, DateFormat.DEFAULT);
152 			dateTimeInstance2 = systemReader.getSimpleDateFormat("Z"); //$NON-NLS-1$
153 			break;
154 		}
155 	}
156 
157 	/**
158 	 * Format committer, author or tagger ident according to this formatter's
159 	 * specification.
160 	 *
161 	 * @param ident
162 	 * @return formatted version of date, time and time zone
163 	 */
164 	@SuppressWarnings("boxing")
165 	public String formatDate(PersonIdent ident) {
166 		switch (format) {
167 		case RAW:
168 			int offset = ident.getTimeZoneOffset();
169 			String sign = offset < 0 ? "-" : "+"; //$NON-NLS-1$ //$NON-NLS-2$
170 			int offset2;
171 			if (offset < 0)
172 				offset2 = -offset;
173 			else
174 				offset2 = offset;
175 			int hours = offset2 / 60;
176 			int minutes = offset2 % 60;
177 			return String.format("%d %s%02d%02d", //$NON-NLS-1$
178 					ident.getWhen().getTime() / 1000, sign, hours, minutes);
179 		case RELATIVE:
180 			return RelativeDateFormatter.format(ident.getWhen());
181 		case LOCALELOCAL:
182 		case LOCAL:
183 			dateTimeInstance.setTimeZone(SystemReader.getInstance()
184 					.getTimeZone());
185 			return dateTimeInstance.format(ident.getWhen());
186 		case LOCALE:
187 			TimeZone tz = ident.getTimeZone();
188 			if (tz == null)
189 				tz = SystemReader.getInstance().getTimeZone();
190 			dateTimeInstance.setTimeZone(tz);
191 			dateTimeInstance2.setTimeZone(tz);
192 			return dateTimeInstance.format(ident.getWhen()) + " " //$NON-NLS-1$
193 					+ dateTimeInstance2.format(ident.getWhen());
194 		default:
195 			tz = ident.getTimeZone();
196 			if (tz == null)
197 				tz = SystemReader.getInstance().getTimeZone();
198 			dateTimeInstance.setTimeZone(ident.getTimeZone());
199 			return dateTimeInstance.format(ident.getWhen());
200 		}
201 	}
202 }