diff --git a/CHANGELOG.md b/CHANGELOG.md index c039bd61998..369d29a3f24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Fixed [#1527](https://github.com/JabRef/jabref/issues/1527): 'Get BibTeX data from DOI' Removes Marking - Fixed [#1592](https://github.com/JabRef/jabref/issues/1592): LibreOffice: wrong numbers in citation labels - Fixed [#1321](https://github.com/JabRef/jabref/issues/1321): LaTeX commands in fields not displayed in the list of references +- Date fields in the BibLatex standard are now always formatted in the correct way, independent of the preferences ### Removed - It is not longer possible to choose to convert HTML sub- and superscripts to equations diff --git a/src/main/java/net/sf/jabref/gui/BasePanel.java b/src/main/java/net/sf/jabref/gui/BasePanel.java index b8368ce3d79..25add509c69 100644 --- a/src/main/java/net/sf/jabref/gui/BasePanel.java +++ b/src/main/java/net/sf/jabref/gui/BasePanel.java @@ -700,7 +700,7 @@ public void update() { tidialog.setVisible(true); if (tidialog.okPressed()) { - UpdateField.setAutomaticFields(Collections.singletonList(bibEntry), false, false); + UpdateField.setAutomaticFields(Collections.singletonList(bibEntry), false, false, Globals.prefs); insertEntry(bibEntry); } }); @@ -898,7 +898,7 @@ private void paste() { firstBE = be; } UpdateField.setAutomaticFields(be, Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_OWNER), - Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP)); + Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP), Globals.prefs); // We have to clone the // entries, since the pasted @@ -1223,7 +1223,7 @@ public BibEntry newEntry(EntryType type) { // Set owner/timestamp if options are enabled: List list = new ArrayList<>(); list.add(be); - UpdateField.setAutomaticFields(list, true, true); + UpdateField.setAutomaticFields(list, true, true, Globals.prefs); // Create an UndoableInsertEntry object. getUndoManager().addEdit(new UndoableInsertEntry(database, be, BasePanel.this)); @@ -1372,7 +1372,7 @@ public void insertEntry(final BibEntry bibEntry) { database.insertEntry(bibEntry); if (Globals.prefs.getBoolean(JabRefPreferences.USE_OWNER)) { // Set owner field to default value - UpdateField.setAutomaticFields(bibEntry, true, true); + UpdateField.setAutomaticFields(bibEntry, true, true, Globals.prefs); } // Create an UndoableInsertEntry object. getUndoManager().addEdit(new UndoableInsertEntry(database, bibEntry, BasePanel.this)); diff --git a/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java b/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java index 33e1ed43528..a026e7363c3 100644 --- a/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java +++ b/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java @@ -707,7 +707,7 @@ private void addSelectedEntries(NamedCompound ce, final List selected) // Set owner/timestamp if options are enabled: UpdateField.setAutomaticFields(selected, Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_OWNER), - Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP)); + Globals.prefs.getBoolean(JabRefPreferences.OVERWRITE_TIME_STAMP), Globals.prefs); // Mark entries if we should if (EntryMarker.shouldMarkEntries()) { diff --git a/src/main/java/net/sf/jabref/gui/date/DatePickerButton.java b/src/main/java/net/sf/jabref/gui/date/DatePickerButton.java index 7752a1ac6bc..d83123de233 100644 --- a/src/main/java/net/sf/jabref/gui/date/DatePickerButton.java +++ b/src/main/java/net/sf/jabref/gui/date/DatePickerButton.java @@ -1,4 +1,5 @@ /* Copyright (C) 2003-2011 Raik Nagel + * 2016 JabRef Contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -26,6 +27,7 @@ import javax.swing.JComponent; import javax.swing.JPanel; +import net.sf.jabref.Globals; import net.sf.jabref.gui.fieldeditors.FieldEditor; import net.sf.jabref.gui.util.FocusRequester; import net.sf.jabref.logic.util.date.EasyDateFormat; @@ -37,9 +39,11 @@ public class DatePickerButton implements ActionListener { private final DatePicker datePicker = new DatePicker(); private final JPanel panel = new JPanel(); private final FieldEditor editor; + private final boolean isoFormat; - public DatePickerButton(FieldEditor pEditor) { + public DatePickerButton(FieldEditor pEditor, Boolean isoFormat) { + this.isoFormat = isoFormat; datePicker.showButtonOnly(true); datePicker.addActionListener(this); datePicker.setShowTodayButton(true); @@ -52,7 +56,11 @@ public DatePickerButton(FieldEditor pEditor) { public void actionPerformed(ActionEvent e) { Date date = datePicker.getDate(); if (date != null) { - editor.setText(new EasyDateFormat().getDateAt(date)); + if (isoFormat) { + editor.setText(EasyDateFormat.isoDateFormat().getDateAt(date)); + } else { + editor.setText(EasyDateFormat.fromPreferences(Globals.prefs).getDateAt(date)); + } // Set focus to editor component after changing its text: new FocusRequester(editor.getTextComponent()); } diff --git a/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java index a1baa112a4b..bdf8892c747 100644 --- a/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java @@ -503,7 +503,7 @@ public Optional getExtra(final FieldEditor editor) { || fieldExtras.contains(FieldProperties.DATE)) { // double click AND datefield => insert the current date (today) return FieldExtraComponents.getDateTimeExtraComponent(editor, - fieldExtras.contains(FieldProperties.DATE)); + fieldExtras.contains(FieldProperties.DATE), fieldExtras.contains(FieldProperties.ISO_DATE)); } else if (fieldExtras.contains(FieldProperties.EXTERNAL)) { return FieldExtraComponents.getExternalExtraComponent(panel, editor); } else if (fieldExtras.contains(FieldProperties.JOURNAL_NAME)) { @@ -1126,10 +1126,10 @@ public void actionPerformed(ActionEvent event) { // Add an UndoableKeyChange to the baseframe's undoManager. UndoableKeyChange undoableKeyChange = new UndoableKeyChange(panel.getDatabase(), entry, oldValue, newValue); - if (TimeStamp.updateTimeStampIsSet()) { + if (TimeStamp.updateTimeStampIsSet(Globals.prefs)) { NamedCompound ce = new NamedCompound(undoableKeyChange.getPresentationName()); ce.addEdit(undoableKeyChange); - TimeStamp.doUpdateTimeStamp(entry) + TimeStamp.doUpdateTimeStamp(entry, Globals.prefs) .ifPresent(fieldChange -> ce.addEdit(new UndoableFieldChange(fieldChange))); ce.end(); panel.getUndoManager().addEdit(ce); @@ -1194,11 +1194,11 @@ public void actionPerformed(ActionEvent event) { // Add an UndoableFieldChange to the baseframe's undoManager. UndoableFieldChange undoableFieldChange = new UndoableFieldChange(entry, fieldEditor.getFieldName(), oldValue, toSet); - if (TimeStamp.updateTimeStampIsSet()) { + if (TimeStamp.updateTimeStampIsSet(Globals.prefs)) { NamedCompound ce = new NamedCompound(undoableFieldChange.getPresentationName()); ce.addEdit(undoableFieldChange); - TimeStamp.doUpdateTimeStamp(entry) + TimeStamp.doUpdateTimeStamp(entry, Globals.prefs) .ifPresent(fieldChange -> ce.addEdit(new UndoableFieldChange(fieldChange))); ce.end(); diff --git a/src/main/java/net/sf/jabref/gui/entryeditor/FieldExtraComponents.java b/src/main/java/net/sf/jabref/gui/entryeditor/FieldExtraComponents.java index f12a5804ea0..78cc26cfdea 100644 --- a/src/main/java/net/sf/jabref/gui/entryeditor/FieldExtraComponents.java +++ b/src/main/java/net/sf/jabref/gui/entryeditor/FieldExtraComponents.java @@ -349,13 +349,14 @@ public static Optional getSelectorExtraComponent(JabRefFrame frame, * @param isDatePicker * @return */ - public static Optional getDateTimeExtraComponent(FieldEditor editor, Boolean isDatePicker) { + public static Optional getDateTimeExtraComponent(FieldEditor editor, Boolean isDatePicker, + Boolean isoFormat) { ((JTextArea) editor).addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) {// double click - String date = new EasyDateFormat().getCurrentDate(); + String date = EasyDateFormat.isoDateFormat().getCurrentDate(); editor.setText(date); } } @@ -363,7 +364,7 @@ public void mouseClicked(MouseEvent e) { // insert a datepicker, if the extras field contains this command if (isDatePicker) { - DatePickerButton datePicker = new DatePickerButton(editor); + DatePickerButton datePicker = new DatePickerButton(editor, isoFormat); return Optional.of(datePicker.getDatePicker()); } else { return Optional.empty(); diff --git a/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java b/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java index 1626c5f72ff..c07c3606bdd 100644 --- a/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java +++ b/src/main/java/net/sf/jabref/gui/plaintextimport/TextInputDialog.java @@ -522,7 +522,7 @@ private boolean parseWithFreeCiteAndAddEntries() { if (importedEntries.isEmpty()) { return false; } else { - UpdateField.setAutomaticFields(importedEntries, false, false); + UpdateField.setAutomaticFields(importedEntries, false, false, Globals.prefs); boolean markEntries = EntryMarker.shouldMarkEntries(); for (BibEntry e : importedEntries) { diff --git a/src/main/java/net/sf/jabref/gui/preftabs/GeneralTab.java b/src/main/java/net/sf/jabref/gui/preftabs/GeneralTab.java index 99284d2b186..8418c326d04 100644 --- a/src/main/java/net/sf/jabref/gui/preftabs/GeneralTab.java +++ b/src/main/java/net/sf/jabref/gui/preftabs/GeneralTab.java @@ -18,7 +18,7 @@ import java.awt.BorderLayout; import java.awt.Component; import java.nio.charset.Charset; -import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; import javax.swing.BorderFactory; import javax.swing.DefaultComboBoxModel; @@ -278,7 +278,7 @@ public void storeSettings() { public boolean validateSettings() { try { // Test if date format is legal: - new SimpleDateFormat(timeStampFormat.getText()); + DateTimeFormatter.ofPattern(timeStampFormat.getText()); } catch (IllegalArgumentException ex2) { JOptionPane.showMessageDialog diff --git a/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java b/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java index 61b8c67cd42..4913fed9b49 100644 --- a/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java +++ b/src/main/java/net/sf/jabref/importer/AppendDatabaseAction.java @@ -142,7 +142,7 @@ private static void mergeFromBibtex(JabRefFrame frame, BasePanel panel, ParserRe for (BibEntry originalEntry : fromDatabase.getEntries()) { BibEntry be = (BibEntry) originalEntry.clone(); be.setId(IdGenerator.next()); - UpdateField.setAutomaticFields(be, overwriteOwner, overwriteTimeStamp); + UpdateField.setAutomaticFields(be, overwriteOwner, overwriteTimeStamp, Globals.prefs); database.insertEntry(be); appendedEntries.add(be); originalEntries.add(originalEntry); diff --git a/src/main/java/net/sf/jabref/importer/EntryFromPDFCreator.java b/src/main/java/net/sf/jabref/importer/EntryFromPDFCreator.java index 83da99a92f8..d47c35e31b5 100644 --- a/src/main/java/net/sf/jabref/importer/EntryFromPDFCreator.java +++ b/src/main/java/net/sf/jabref/importer/EntryFromPDFCreator.java @@ -2,7 +2,8 @@ import java.io.File; import java.io.IOException; -import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.List; import java.util.Optional; @@ -95,8 +96,8 @@ private void addEntryDataFromPDDocumentInformation(File pdfFile, BibEntry entry) Calendar creationDate = pdfDocInfo.getCreationDate(); if (creationDate != null) { // default time stamp follows ISO-8601. Reason: https://xkcd.com/1179/ - String date = new SimpleDateFormat("yyyy-MM-dd") - .format(creationDate.getTime()); + String date = LocalDate.of(creationDate.YEAR, creationDate.MONTH + 1, creationDate.DAY_OF_MONTH) + .format(DateTimeFormatter.ISO_LOCAL_DATE); appendToField(entry, Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD), date); } diff --git a/src/main/java/net/sf/jabref/importer/ImportMenuItem.java b/src/main/java/net/sf/jabref/importer/ImportMenuItem.java index 61225333265..8c08eb3eda3 100644 --- a/src/main/java/net/sf/jabref/importer/ImportMenuItem.java +++ b/src/main/java/net/sf/jabref/importer/ImportMenuItem.java @@ -258,7 +258,7 @@ private ParserResult mergeImportResults(List getSelectableZipEntries(ZipFile zipFile) { List entries = new ArrayList<>(); Enumeration e = zipFile.entries(); for (ZipEntry entry : Collections.list(e)) { @@ -158,7 +162,7 @@ private static ZipEntry[] getSelectableZipEntries(ZipFile zipFile) { entries.add(entry); } } - return entries.toArray(new ZipEntry[entries.size()]); + return entries; } /* @@ -188,13 +192,13 @@ public Dimension getSize() { */ private static class ZipFileChooserTableModel extends AbstractTableModel { - private final String[] columnNames = new String[] {Localization.lang("Name"), - Localization.lang("Last modified"), Localization.lang("Size")}; - private final ZipEntry[] rows; + private final List columnNames = Arrays.asList(Localization.lang("Name"), + Localization.lang("Last modified"), Localization.lang("Size")); + private final List rows; private final ZipFile zipFile; - ZipFileChooserTableModel(ZipFile zipFile, ZipEntry[] rows) { + ZipFileChooserTableModel(ZipFile zipFile, List rows) { super(); this.rows = rows; this.zipFile = zipFile; @@ -206,7 +210,7 @@ private static class ZipFileChooserTableModel extends AbstractTableModel { */ @Override public int getColumnCount() { - return columnNames.length; + return columnNames.size(); } /* @@ -215,7 +219,7 @@ public int getColumnCount() { */ @Override public int getRowCount() { - return this.rows.length; + return this.rows.size(); } /* @@ -224,7 +228,7 @@ public int getRowCount() { */ @Override public String getColumnName(int col) { - return columnNames[col]; + return columnNames.get(col); } /** @@ -234,7 +238,7 @@ public String getColumnName(int col) { * @return Zip file entry */ public ZipEntry getZipEntry(int rowIndex) { - return this.rows[rowIndex]; + return this.rows.get(rowIndex); } /** @@ -257,7 +261,9 @@ public Object getValueAt(int rowIndex, int columnIndex) { if (columnIndex == 0) { value = entry.getName(); } else if (columnIndex == 1) { - value = SimpleDateFormat.getDateTimeInstance().format(new Date(entry.getTime())); + value = ZonedDateTime.ofInstant(new Date(entry.getTime()).toInstant(), + ZoneId.systemDefault()) + .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)); } else if (columnIndex == 2) { value = entry.getSize(); } diff --git a/src/main/java/net/sf/jabref/logic/layout/format/CurrentDate.java b/src/main/java/net/sf/jabref/logic/layout/format/CurrentDate.java index 935f5164642..8fcdecaf906 100644 --- a/src/main/java/net/sf/jabref/logic/layout/format/CurrentDate.java +++ b/src/main/java/net/sf/jabref/logic/layout/format/CurrentDate.java @@ -1,5 +1,5 @@ /* - Copyright (C) 2005-2015 Andreas Rudert, Oscar Gustafsson + Copyright (C) 2005-2016 Andreas Rudert, Oscar Gustafsson All programs in this directory and subdirectories are published under the GNU General Public License as @@ -25,15 +25,15 @@ */ package net.sf.jabref.logic.layout.format; -import java.text.SimpleDateFormat; -import java.util.Date; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import net.sf.jabref.logic.layout.LayoutFormatter; /** * Inserts the current date (the time a database is being exported). * - *

If a fieldText is given, it must be a valid {@link SimpleDateFormat} pattern. + *

If a fieldText is given, it must be a valid {@link DateTimeFormatter} pattern. * If none is given, the format pattern will be yyyy-MM-dd hh:mm:ss z. * This follows ISO-8601. Reason: https://xkcd.com/1179/.

* @@ -55,6 +55,6 @@ public String format(String fieldText) { if ((fieldText != null) && (fieldText.trim() != null) && !fieldText.trim().isEmpty()) { format = fieldText; } - return new SimpleDateFormat(format).format(new Date()); + return ZonedDateTime.now().format(DateTimeFormatter.ofPattern(format)); } } diff --git a/src/main/java/net/sf/jabref/logic/net/Cookie.java b/src/main/java/net/sf/jabref/logic/net/Cookie.java index 12f5aafac99..0de20c502b5 100644 --- a/src/main/java/net/sf/jabref/logic/net/Cookie.java +++ b/src/main/java/net/sf/jabref/logic/net/Cookie.java @@ -16,10 +16,9 @@ package net.sf.jabref.logic.net; import java.net.URI; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.Locale; import java.util.Optional; @@ -28,15 +27,15 @@ class Cookie { private final String name; private final String value; private String domain; - private Date expires; + private ZonedDateTime expires; private String path; - /** - * DateFormats should not be reused among instances (or rather among threads), because they are not thread-safe. - * If they are shared, their usage should be synchronized. - */ - private final DateFormat whiteSpaceFormat = new SimpleDateFormat("E, dd MMM yyyy k:m:s 'GMT'", Locale.US); - private final DateFormat hyphenFormat = new SimpleDateFormat("E, dd-MMM-yyyy k:m:s 'GMT'", Locale.US); + private final DateTimeFormatter whiteSpaceFormat = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", + Locale.ROOT); + private final DateTimeFormatter hyphenFormat = DateTimeFormatter.ofPattern("EEE, dd-MMM-yyyy HH:mm:ss z", + Locale.ROOT); + private final DateTimeFormatter hyphenTwoDigitYearFormat = DateTimeFormatter.ofPattern("EEE, dd-MMM-yy HH:mm:ss z", + Locale.ROOT); /** @@ -48,10 +47,8 @@ class Cookie { public Cookie(URI uri, String header) { String[] attributes = header.split(";"); String nameValue = attributes[0].trim(); - this.name = - nameValue.substring(0, nameValue.indexOf('=')); - this.value = - nameValue.substring(nameValue.indexOf('=') + 1); + this.name = nameValue.substring(0, nameValue.indexOf('=')); + this.value = nameValue.substring(nameValue.indexOf('=') + 1); this.path = "/"; this.domain = uri.getHost(); @@ -82,13 +79,16 @@ public Cookie(URI uri, String header) { this.path = value; } else if ("expires".equalsIgnoreCase(name)) { try { - this.expires = whiteSpaceFormat.parse(value); - } catch (ParseException e) { + this.expires = ZonedDateTime.parse(value, whiteSpaceFormat); + } catch (DateTimeParseException e) { try { - this.expires = hyphenFormat.parse(value); - } catch (ParseException e2) { - throw new IllegalArgumentException( - "Bad date format in header: " + value); + this.expires = ZonedDateTime.parse(value, hyphenFormat); + } catch (DateTimeParseException e2) { + try { + this.expires = ZonedDateTime.parse(value, hyphenTwoDigitYearFormat); + } catch (DateTimeParseException e3) { + throw new IllegalArgumentException("Bad date format in header: " + value); + } } } } @@ -99,8 +99,7 @@ public boolean hasExpired() { if (expires == null) { return false; } - Date now = new Date(); - return now.after(expires); + return ZonedDateTime.now().isAfter(expires); } /** diff --git a/src/main/java/net/sf/jabref/logic/util/UpdateField.java b/src/main/java/net/sf/jabref/logic/util/UpdateField.java index 942237de30a..deea9ed497d 100644 --- a/src/main/java/net/sf/jabref/logic/util/UpdateField.java +++ b/src/main/java/net/sf/jabref/logic/util/UpdateField.java @@ -3,7 +3,6 @@ import java.util.Collection; import java.util.Optional; -import net.sf.jabref.Globals; import net.sf.jabref.logic.util.date.EasyDateFormat; import net.sf.jabref.model.FieldChange; import net.sf.jabref.model.entry.BibEntry; @@ -12,9 +11,6 @@ public class UpdateField { - private static final EasyDateFormat DATE_FORMATTER = new EasyDateFormat(); - - /** * Updating a field will result in the entry being reformatted on save * @@ -88,13 +84,14 @@ public static Optional updateField(BibEntry be, String field, Strin * @param overwriteOwner Indicates whether owner should be set if it is already set. * @param overwriteTimestamp Indicates whether timestamp should be set if it is already set. */ - public static void setAutomaticFields(BibEntry entry, boolean overwriteOwner, boolean overwriteTimestamp) { - String defaultOwner = Globals.prefs.get(JabRefPreferences.DEFAULT_OWNER); - String timestamp = DATE_FORMATTER.getCurrentDate(); - String timeStampField = Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD); - boolean setOwner = Globals.prefs.getBoolean(JabRefPreferences.USE_OWNER) + public static void setAutomaticFields(BibEntry entry, boolean overwriteOwner, boolean overwriteTimestamp, + JabRefPreferences prefs) { + String defaultOwner = prefs.get(JabRefPreferences.DEFAULT_OWNER); + String timestamp = EasyDateFormat.fromPreferences(prefs).getCurrentDate(); + String timeStampField = prefs.get(JabRefPreferences.TIME_STAMP_FIELD); + boolean setOwner = prefs.getBoolean(JabRefPreferences.USE_OWNER) && (overwriteOwner || (!entry.hasField(FieldName.OWNER))); - boolean setTimeStamp = Globals.prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP) + boolean setTimeStamp = prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP) && (overwriteTimestamp || (!entry.hasField(timeStampField))); setAutomaticFields(entry, setOwner, defaultOwner, setTimeStamp, timeStampField, timestamp); @@ -121,19 +118,19 @@ private static void setAutomaticFields(BibEntry entry, boolean setOwner, String * @param bibs List of bibtex entries */ public static void setAutomaticFields(Collection bibs, boolean overwriteOwner, - boolean overwriteTimestamp) { + boolean overwriteTimestamp, JabRefPreferences prefs) { - boolean globalSetOwner = Globals.prefs.getBoolean(JabRefPreferences.USE_OWNER); - boolean globalSetTimeStamp = Globals.prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP); + boolean globalSetOwner = prefs.getBoolean(JabRefPreferences.USE_OWNER); + boolean globalSetTimeStamp = prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP); // Do not need to do anything if all options are disabled if (!(globalSetOwner || globalSetTimeStamp)) { return; } - String timeStampField = Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD); - String defaultOwner = Globals.prefs.get(JabRefPreferences.DEFAULT_OWNER); - String timestamp = DATE_FORMATTER.getCurrentDate(); + String timeStampField = prefs.get(JabRefPreferences.TIME_STAMP_FIELD); + String defaultOwner = prefs.get(JabRefPreferences.DEFAULT_OWNER); + String timestamp = EasyDateFormat.fromPreferences(prefs).getCurrentDate(); // Iterate through all entries for (BibEntry curEntry : bibs) { diff --git a/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java b/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java index 22e70f8c179..cbef4f15af0 100644 --- a/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java +++ b/src/main/java/net/sf/jabref/logic/util/date/EasyDateFormat.java @@ -1,9 +1,10 @@ package net.sf.jabref.logic.util.date; -import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; -import net.sf.jabref.Globals; import net.sf.jabref.preferences.JabRefPreferences; public class EasyDateFormat { @@ -11,9 +12,17 @@ public class EasyDateFormat { /** * The formatter objects */ - private SimpleDateFormat dateFormatter; + private final DateTimeFormatter dateFormatter; + public EasyDateFormat(String dateFormat) { + this(DateTimeFormatter.ofPattern(dateFormat)); + } + + public EasyDateFormat(DateTimeFormatter dateFormatter) { + this.dateFormatter = dateFormatter; + } + /** * Creates a String containing the current date (and possibly time), * formatted according to the format set in preferences under the key @@ -22,7 +31,7 @@ public class EasyDateFormat { * @return The date string. */ public String getCurrentDate() { - return getDateAt(new Date()); + return getDateAt(ZonedDateTime.now()); } /** @@ -32,11 +41,26 @@ public String getCurrentDate() { * @return The formatted date string. */ public String getDateAt(Date date) { + return getDateAt(date.toInstant().atZone(ZoneId.systemDefault())); + } + + /** + * Creates a readable Date string from the parameter date. The format is set + * in preferences under the key "timeStampFormat". + * + * @return The formatted date string. + */ + public String getDateAt(ZonedDateTime dateTime) { // first use, create an instance - if (dateFormatter == null) { - String format = Globals.prefs.get(JabRefPreferences.TIME_STAMP_FORMAT); - dateFormatter = new SimpleDateFormat(format); - } - return dateFormatter.format(date); + return dateTime.format(dateFormatter); + } + + + public static EasyDateFormat fromPreferences(JabRefPreferences preferences) { + return new EasyDateFormat(preferences.get(JabRefPreferences.TIME_STAMP_FORMAT)); + } + + public static EasyDateFormat isoDateFormat() { + return new EasyDateFormat(DateTimeFormatter.ISO_LOCAL_DATE); } } diff --git a/src/main/java/net/sf/jabref/logic/util/date/TimeStamp.java b/src/main/java/net/sf/jabref/logic/util/date/TimeStamp.java index f1de485b2c5..b2ac885a185 100644 --- a/src/main/java/net/sf/jabref/logic/util/date/TimeStamp.java +++ b/src/main/java/net/sf/jabref/logic/util/date/TimeStamp.java @@ -2,7 +2,6 @@ import java.util.Optional; -import net.sf.jabref.Globals; import net.sf.jabref.logic.util.UpdateField; import net.sf.jabref.model.FieldChange; import net.sf.jabref.model.entry.BibEntry; @@ -10,20 +9,17 @@ public class TimeStamp { - private static final EasyDateFormat DATE_FORMATTER = new EasyDateFormat(); - - public static boolean updateTimeStampIsSet() { - return Globals.prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP) - && Globals.prefs.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP); + public static boolean updateTimeStampIsSet(JabRefPreferences prefs) { + return prefs.getBoolean(JabRefPreferences.USE_TIME_STAMP) + && prefs.getBoolean(JabRefPreferences.UPDATE_TIMESTAMP); } /** - * Updates the timestamp of the given entry, nests the given undaoableEdit in a named compound, and returns that - * named compound + * Updates the timestamp of the given entry and returns the FieldChange */ - public static Optional doUpdateTimeStamp(BibEntry entry) { - String timeStampField = Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD); - String timestamp = DATE_FORMATTER.getCurrentDate(); + public static Optional doUpdateTimeStamp(BibEntry entry, JabRefPreferences prefs) { + String timeStampField = prefs.get(JabRefPreferences.TIME_STAMP_FIELD); + String timestamp = EasyDateFormat.fromPreferences(prefs).getCurrentDate(); return UpdateField.updateField(entry, timeStampField, timestamp); } diff --git a/src/main/java/net/sf/jabref/model/entry/FieldProperties.java b/src/main/java/net/sf/jabref/model/entry/FieldProperties.java index 972c687ae85..d92a764ecd6 100644 --- a/src/main/java/net/sf/jabref/model/entry/FieldProperties.java +++ b/src/main/java/net/sf/jabref/model/entry/FieldProperties.java @@ -23,7 +23,8 @@ public enum FieldProperties { EDITOR_TYPE, PAGINATION, TYPE, - CROSSREF; + CROSSREF, + ISO_DATE; public static final Set ALL_OPTS = EnumSet.allOf(FieldProperties.class); diff --git a/src/main/java/net/sf/jabref/model/entry/InternalBibtexFields.java b/src/main/java/net/sf/jabref/model/entry/InternalBibtexFields.java index b5e1b076e51..3025e93f9ee 100644 --- a/src/main/java/net/sf/jabref/model/entry/InternalBibtexFields.java +++ b/src/main/java/net/sf/jabref/model/entry/InternalBibtexFields.java @@ -176,7 +176,8 @@ private InternalBibtexFields(boolean serializeSpecialFields) { add(new BibtexSingleField(FieldName.EID, true, BibtexSingleField.SMALL_W)); dummy = new BibtexSingleField(FieldName.DATE, true); - dummy.setPrivate(); + dummy.setExtras(EnumSet.of(FieldProperties.DATE)); + dummy.setPrivate(); // TODO: Why private? add(dummy); add(new BibtexSingleField("pmid", false, BibtexSingleField.SMALL_W, 60).setNumeric(true)); @@ -293,6 +294,7 @@ private InternalBibtexFields(boolean serializeSpecialFields) { field = new BibtexSingleField(fieldText, true, BibtexSingleField.SMALL_W); } field.getExtras().add(FieldProperties.DATE); + field.getExtras().add(FieldProperties.ISO_DATE); add(field); } diff --git a/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java b/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java index 0b8e1e77867..1aad683d64d 100644 --- a/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java +++ b/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java @@ -281,7 +281,7 @@ private BibEntry createNewEntry() { // Set owner/timestamp if options are enabled: List list = new ArrayList<>(); list.add(be); - UpdateField.setAutomaticFields(list, true, true); + UpdateField.setAutomaticFields(list, true, true, Globals.prefs); // Create an UndoableInsertEntry object. panel.getUndoManager().addEdit(new UndoableInsertEntry(panel.getDatabase(), be, panel)); diff --git a/src/test/java/net/sf/jabref/logic/net/CookieTest.java b/src/test/java/net/sf/jabref/logic/net/CookieTest.java new file mode 100644 index 00000000000..c1f23cbfb8b --- /dev/null +++ b/src/test/java/net/sf/jabref/logic/net/CookieTest.java @@ -0,0 +1,40 @@ +package net.sf.jabref.logic.net; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + + +public class CookieTest { + + @Test + public void testCookieHyphenFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25-Jul-2017 16:43:15 GMT"); + } + + @Test + public void testCookieHyphenTwoDigitYearFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25-Jul-17 16:43:15 GMT"); + } + + @Test + public void testCookieSpaceFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25 Jul 2017 16:43:15 GMT"); + } + + @Test + public void testHasExpiredFalse() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25-Jul-45 16:43:15 GMT"); + assertFalse(cookie.hasExpired()); + } + + @Test + public void testHasExpiredTrue() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("hhh"), "name=Nicholas; expires=Sat, 02 May 2009 23:38:25 GMT"); + assertTrue(cookie.hasExpired()); + } +}