【发布时间】:2021-05-04 12:00:31
【问题描述】:
这个例子有 2 列数据。
第 1 列是没有毫秒的日期,第 2 列是有毫秒的数据。
显示允许用户更改日期格式。关键是第 1 列不应包含毫秒,而第 2 列应始终包含毫秒。
如果日期格式为 dd-MM-yyyy HH:mm:ss,则在处理第 2 列中的数据时,代码可以简单地附加“.SSS”,但格式可能会有很大差异。例如,它甚至可以是“MM-dd-yy”而不包括任何时间参考,但第二列应始终包括时间和毫秒。
这里是代码。有额外的杂项代码只是为了确保毫秒是第一次可见。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
public class DateFormatRendererExample
{
public static void main(String[] args)
{
DateExampleSetup dateExampleSetup = new DateExampleSetup ();
}
}
class DateExampleSetup extends JFrame
{
final static Class[] columnClass = new Class[] { Date.class, Date.class };
String currentDateFormat = "MM-dd-yyyy HH:mm:ss";
String oldDateFormat = "MM-dd-yyyy HH:mm:ss";
MyTableModel model;
public DateExampleSetup()
{
model = new MyTableModel();
model.addRow("05-22-2020 12:12:12", "06-02-2020 20:11:55.123");
model.addRow("10-18-2020 14:16:17", "01-02-2020 09:09:49.567");
JTable table = new JTable(model);
table.setDefaultRenderer(Date.class, new MyDateCellRenderer(this));
JTextField dateFormatField = new JTextField(20);
dateFormatField.setText(currentDateFormat);
JButton activateDateFormat = new JButton("Activate new Date Format");
activateDateFormat.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0)
{
setCurrentDateFormat(dateFormatField.getText());
MyTableModel newModel = new MyTableModel ();
newModel.addRow("05-22-2020 12:12:12", "06-02-2020 20:11:55.1234");
newModel.addRow("10-18-2020 14:16:17", "02-02-2020 09:09:49.5678");
table.setModel(newModel);
newModel.fireTableDataChanged();
setOldDateFormat(getCurrentDateFormat());
}
});
setLayout(new BorderLayout());
add(dateFormatField, BorderLayout.NORTH);
add(table, BorderLayout.CENTER);
add(activateDateFormat, BorderLayout.SOUTH);
setVisible(true);
setSize(500,300);
}
public String getCurrentDateFormat()
{
return currentDateFormat;
}
public void setCurrentDateFormat(String newCurrent)
{
currentDateFormat = newCurrent;
}
public String getOldDateFormat()
{
return oldDateFormat;
}
public void setOldDateFormat(String newCurrent)
{
currentDateFormat = newCurrent;
}
}
class MyDateCellRenderer extends JLabel implements TableCellRenderer
{
DateExampleSetup des;
boolean firstTimeRow1 = true;
boolean firstTimeRow2 = true;
public MyDateCellRenderer(DateExampleSetup des)
{
super();
this.des = des;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int col) {
try
{
///Just to get the milliseconds to show the first time.
if (firstTimeRow1 && row == 0 && col == 1)
{
SimpleDateFormat tempDateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss.SSS");
Date tempDate = null;
tempDate = tempDateFormat.parse((String)value);
value = tempDateFormat.format(tempDate);
setText(value.toString());
firstTimeRow1 = false;
}
else if (firstTimeRow2 && row == 1 && col == 1)
{
SimpleDateFormat tempDateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss.SSS");
Date tempDate = null;
tempDate = tempDateFormat.parse((String)value);
value = tempDateFormat.format(tempDate);
setText(value.toString());
firstTimeRow2 = false;
}
else
{
SimpleDateFormat oldDateFormat = new SimpleDateFormat(des.getOldDateFormat());
SimpleDateFormat newDateFormat = new SimpleDateFormat(des.getCurrentDateFormat());
Date date = null;
date = oldDateFormat.parse((String)value);
value = newDateFormat.format(date);
setText(value.toString());
}
}
catch (ParseException e)
{
e.printStackTrace();
}
return this;
}
}
class MyTableModel extends AbstractTableModel {
private List<String[]> rows;
private String columnNames[] = { "Regular Date ", "Date with milliseconds"};
public MyTableModel() {
rows = new ArrayList<>(25);
}
@Override
public int getRowCount() {
return rows.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return Date.class;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
String[] row = rows.get(rowIndex);
return row[columnIndex];
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
public void addRow(String s1, String s2)
{
String[] row = new String[getColumnCount()];
row[0] = s1;
row[1] = s2;
rows.add(row);
fireTableRowsInserted(getRowCount(), getRowCount());
}
}
执行时会显示以下帧。注意第二列有毫秒。
当日期更改为“dd-MM-yyyy”并按下“激活新日期格式”按钮时,第 2 列中的日期会丢失小时、分钟和秒,尤其是毫秒。
是否可以在确保 HH:mm:ss.sss 始终存在的同时对一列使用单一日期格式(几乎可以是任何格式)同时对另一列使用相同的格式?
【问题讨论】:
-
我建议你不要使用
SimpleDateFormat和Date。这些类设计不良且过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time API 的LocalDateTime和DateTimeFormatter。 -
用户或其他人是否提供格式?如果提供给您
HH dd MMM yyyy,那么第 2 列应该使用什么格式? -
初始日期格式是默认的,因此当数据最初加载时,每个列/日期都有自己的格式,但是有一个选项允许之后更改日期格式,并且很少包括毫秒但对于第二个日期列很重要。
-
不清楚,抱歉。默认值从何而来?对我来说,从源头修复格式以确保第 2 列的格式已经包含毫秒,这听起来很简单。
标签: java simpledateformat milliseconds