View Javadoc

1   package org.jrobin.core.timespec;
2   
3   import org.jrobin.core.RrdException;
4   import org.jrobin.core.Util;
5   
6   import javax.swing.*;
7   import java.awt.*;
8   import java.awt.event.ActionEvent;
9   import java.awt.event.ActionListener;
10  import java.text.ParseException;
11  import java.text.SimpleDateFormat;
12  import java.util.Date;
13  
14  /**
15   * Small swing-based utility to convert timestamps (seconds since epoch) to readable dates and vice versa.
16   * Supports at-style time specification (like "now-2d", "noon yesterday") and other human-readable
17   * data formats:<p>
18   * <ul>
19   * <li>MM/dd/yy HH:mm:ss
20   * <li>dd.MM.yy HH:mm:ss
21   * <li>dd.MM.yy HH:mm:ss
22   * <li>MM/dd/yy HH:mm
23   * <li>dd.MM.yy HH:mm
24   * <li>yy-MM-dd HH:mm
25   * <li>MM/dd/yy
26   * <li>dd.MM.yy
27   * <li>yy-MM-dd
28   * <li>HH:mm MM/dd/yy
29   * <li>HH:mm dd.MM.yy
30   * <li>HH:mm yy-MM-dd
31   * <li>HH:mm:ss MM/dd/yy
32   * <li>HH:mm:ss dd.MM.yy
33   * <li>HH:mm:ss yy-MM-dd
34   * </ul>
35   * The current timestamp is displayed in the title bar :)<p>
36   */
37  public class Epoch extends JFrame {
38  	private static final long serialVersionUID = 1L;
39  	private static final String[] supportedFormats = {
40  			"MM/dd/yy HH:mm:ss", "dd.MM.yy HH:mm:ss", "yy-MM-dd HH:mm:ss", "MM/dd/yy HH:mm",
41  			"dd.MM.yy HH:mm", "yy-MM-dd HH:mm", "MM/dd/yy", "dd.MM.yy", "yy-MM-dd", "HH:mm MM/dd/yy",
42  			"HH:mm dd.MM.yy", "HH:mm yy-MM-dd", "HH:mm:ss MM/dd/yy", "HH:mm:ss dd.MM.yy", "HH:mm:ss yy-MM-dd"
43  	};
44  
45  	private static final SimpleDateFormat[] parsers = new SimpleDateFormat[supportedFormats.length];
46  	private static final String helpText;
47  
48  	private Timer timer = new Timer(1000, new ActionListener() {
49  		public void actionPerformed(ActionEvent e) {
50  			showTimestamp();
51  		}
52  	});
53  
54  	static {
55  		for (int i = 0; i < parsers.length; i++) {
56  			parsers[i] = new SimpleDateFormat(supportedFormats[i]);
57  			parsers[i].setLenient(true);
58  		}
59  		StringBuffer tooltipBuff = new StringBuffer("<html><b>Supported input formats:</b><br>");
60  		for (String supportedFormat : supportedFormats) {
61  			tooltipBuff.append(supportedFormat).append("<br>");
62  		}
63  		tooltipBuff.append("<b>AT-style time specification</b><br>");
64  		tooltipBuff.append("timestamp<br><br>");
65  		tooltipBuff.append("Copyright (C) 2003-2005 Sasa Markovic, All Rights Reserved</html>");
66  		helpText = tooltipBuff.toString();
67  	}
68  
69  	private JLabel topLabel = new JLabel("Enter timestamp or readable date:");
70  	private JTextField inputField = new JTextField(25);
71  	private JButton convertButton = new JButton("Convert");
72  	private JButton helpButton = new JButton("Help");
73  
74  	private static final SimpleDateFormat OUTPUT_DATE_FORMAT =
75  			new SimpleDateFormat("MM/dd/yy HH:mm:ss EEE");
76  
77  	Epoch() {
78  		super("Epoch");
79  		constructUI();
80  		timer.start();
81  	}
82  
83  	private void constructUI() {
84  		JPanel c = (JPanel) getContentPane();
85  		c.setLayout(new BorderLayout(3, 3));
86  		c.add(topLabel, BorderLayout.NORTH);
87  		c.add(inputField, BorderLayout.WEST);
88  		c.add(convertButton, BorderLayout.CENTER);
89  		convertButton.setToolTipText(helpText);
90  		convertButton.addActionListener(new ActionListener() {
91  			public void actionPerformed(ActionEvent e) {
92  				convert();
93  			}
94  		});
95  		c.add(helpButton, BorderLayout.EAST);
96  		helpButton.addActionListener(new ActionListener() {
97  			public void actionPerformed(ActionEvent e) {
98  				JOptionPane.showMessageDialog(helpButton, helpText, "Epoch Help", JOptionPane.INFORMATION_MESSAGE);
99  			}
100 		});
101 		inputField.requestFocus();
102 		getRootPane().setDefaultButton(convertButton);
103 		setResizable(false);
104 		setDefaultCloseOperation(EXIT_ON_CLOSE);
105 		pack();
106 		centerOnScreen();
107 		setVisible(true);
108 	}
109 
110 	void centerOnScreen() {
111 		Toolkit t = Toolkit.getDefaultToolkit();
112 		Dimension screenSize = t.getScreenSize();
113 		Dimension frameSize = getPreferredSize();
114 		double x = (screenSize.getWidth() - frameSize.getWidth()) / 2;
115 		double y = (screenSize.getHeight() - frameSize.getHeight()) / 2;
116 		setLocation((int) x, (int) y);
117 	}
118 
119 	private void convert() {
120 		String time = inputField.getText().trim();
121 		if (time.length() > 0) {
122 			// try simple timestamp
123 			try {
124 				long timestamp = Long.parseLong(time);
125 				Date date = new Date(timestamp * 1000L);
126 				formatDate(date);
127 			}
128 			catch (NumberFormatException nfe) {
129 				// failed, try as a date
130 				try {
131 					inputField.setText("" + parseDate(time));
132 				}
133 				catch (RrdException e) {
134 					inputField.setText("Could not convert, sorry");
135 				}
136 			}
137 		}
138 	}
139 
140 	private void showTimestamp() {
141 		long timestamp = Util.getTime();
142 		setTitle(timestamp + " seconds since epoch");
143 	}
144 
145 	void formatDate(Date date) {
146 		inputField.setText(OUTPUT_DATE_FORMAT.format(date));
147 	}
148 
149 	private long parseDate(String time) throws RrdException {
150 		for (SimpleDateFormat parser : parsers) {
151 			try {
152 				return Util.getTimestamp(parser.parse(time));
153 			}
154 			catch (ParseException e) {
155 				// NOP
156 			}
157 		}
158 		return new TimeParser(time).parse().getTimestamp();
159 	}
160 
161 	/**
162 	 * Main method which runs this utility.
163 	 *
164 	 * @param args Not used.
165 	 */
166 	public static void main(String[] args) {
167 		new Epoch();
168 	}
169 }