diff --git a/appinfo.properties b/appinfo.properties
index aa3f2775..4f86d292 100644
--- a/appinfo.properties
+++ b/appinfo.properties
@@ -1,10 +1,10 @@
-#Everything can be manually updated except buildnum and builddate.
-#Fri, 05 Jun 2020 19:37:35 +0200
-program.BUILDNUM=1700
-program.AUTHOR=Morten Johannes Ervik, CSU/IARC
-program.BUILDDATE=20200605193735
-program.DESCRIPTION=CanReg5 is a multi user, multi platform, open source tool to input, store, check and analyse cancer registry data.
-program.COPYRIGHT=2008-2019
-program.VERSION=5.00.44b
-program.COMPANY=International Agency for Research on Cancer
-program.PROGNAME=CanReg
+#Everything can be manually updated except buildnum and builddate.
+#Wed, 17 Jun 2020 12:17:55 +0200
+program.BUILDNUM=1702
+program.AUTHOR=Morten Johannes Ervik, CSU/IARC
+program.BUILDDATE=20200617121755
+program.DESCRIPTION=CanReg5 is a multi user, multi platform, open source tool to input, store, check and analyse cancer registry data.
+program.COPYRIGHT=2008-2020
+program.VERSION=5.00.44c
+program.COMPANY=International Agency for Research on Cancer
+program.PROGNAME=CanReg
diff --git a/buildnumber.properties b/buildnumber.properties
index 7a866ae1..dc3307dd 100644
--- a/buildnumber.properties
+++ b/buildnumber.properties
@@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit!
-#Fri Jun 05 19:37:35 CEST 2020
-build.number=1701
+#Wed Jun 17 12:17:55 CEST 2020
+build.number=1703
diff --git a/changelog.txt b/changelog.txt
index 43071b11..20b6d28e 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,8 @@
Changelog
+5.00.44c
+- Fixed a bug in recording of unknown dates.
+
5.00.44b
- Table builder is now compatible with latest version of R. (4.0.0)
- Population data sets with different reference populations are not compatible.
diff --git a/inno-settings.txt b/inno-settings.txt
index f764cf5d..7fcc090c 100644
--- a/inno-settings.txt
+++ b/inno-settings.txt
@@ -1 +1 @@
-#define MyAppVersion "5.00.44b"
+#define MyAppVersion "5.00.44c"
diff --git a/src/canreg/client/gui/resources/about.html b/src/canreg/client/gui/resources/about.html
index 67727774..6695aff2 100644
--- a/src/canreg/client/gui/resources/about.html
+++ b/src/canreg/client/gui/resources/about.html
@@ -1,110 +1,110 @@
-
-
-
-
- CanReg5: About
-
-
-
- Copyright
- © 2008-2019
- International Agency for Research on Cancer
World Health
- Organization
All rights reserved. (Licensing information)
- Credits
- Lead developement and design:
- Morten Johannes Ervik, IARC/CSU
-
- Additional developement:
- Andy Cooke (Original quality control module)
- Jacques Ferlay (Original PostScript code and conversion tables)
- Mathieu Laversanne (R code for analysis)
- Sebastien Antoni (R code for analysis)
- Anahita Rahimi (R code for analysis)
- Hemant Dhivar (Migration Tool)
- Betty Carballo and Patricio Carranza (New Dataentry form, bug fixes)
-
- Additional design:
- Andy Cooke
- Maria Paula Curado
- Lydia Voti, IARC/SCR
- Freddie Bray
- David Forman
- Max Parkin
-
- Consultants:
- Philippe Autier, IARC/BIO
- Hoda Anton-Culver, University of California Irvine, USA
- Joe Harford, NCI, USA
- Hai-Rim Shin, IARC/DEA
- John Young, Emory University, USA
-
- Technical consultants:
- Michel Smans, IARC/ITS
- Lucile Alteyrac, IARC/BIO
-
- Thanks:
- Kai Toedter (JCalendar)
- Jeremy Dickson (CachingTableAPI)
- Alexandre Moore (Icons)
- Brian Cole (PagingTableModel)
- Stephen Kelvin (XTableColumnModel)
- Ashok Banerjee and Jignesh Mehta (ExcelAdapter)
- Glen Smith et al (opencsv)
- Dem Pilafian (Bare Bones Browser Launch)
- Jesse Wilson (Glazed Lists)
- Frank Tang (juniversalchardet)
- Object REfinery Limited (JFreeChart)
- Chris Evans (jcommons)
- The Buzz Media (imgscalr – Java Image Scaling Library)
- The Apache Software Foundation (Batik)
- iText Software Corp (iText)
-
- Testers:
- Mathieu Mazuir, IARC/DEP
- Antoine Buemi, Registre des Cancers du Haut-Rhin
-
- Beta-testers:
- Xenios Anastassiades, Ministry of Health, Cyprus
- Deborah Bringman, University of California Irvine, USA
- Amr Ebeid, Gharbiah Cancer Registry, Egypt
- Ibrahim Abd-Elbar Seif Eldin, Gharbiah Cancer Registry, Egypt
- Sarah Marshall, University of California Irvine, USA
- Omar Nimri, Jordan Cancer Registry, Jordan
- M. Ramadan, Gharbiah Cancer Registry, Egypt
- Kevin Ward, Emory University, USA
- Cankut Yakut, Izmir Cancer Registry, Turkey
-
- Translators:
- French: Joannie Lortet-Tieulent, IARC, France
- Portugese: Edesio Martins, Goiania Cancer Registry, Brazil
- Russian: Evgeniya Ostroumova, IARC, France and Anton Ryzhov, Ukraine
- Spanish: Graciela Cristina Nicolas, Cordoba, Argentina
- Chinese: Yayun Dai, IARC, France and Shixuan Liu, China
- Portugese, Portugal: Gonçalo Lacerda, Azores, Portugal
- Turkish: Cankut Yakut, Izmir Cancer Registry, Turkey
-
- References:
-
- J Ferlay et al, Check and Conversion Programs for Cancer Registries (IARC/IACR Tools for Cancer Registries), IARC Technical Report No. 42, Lyon, 2005 (Available at: http://www.iacr.com.fr/TR42.htm)
- O.M. Jensen et al, Cancer Registration: Principles and Methods, IARC Scientific Publication No. 95, Lyon, 1991 (Available online at http://www.iarc.fr./en/publications/pdfs-online/epi/sp95/index.php)
- E Steliarova-Foucher et al, Childhood Classification, Third Edition, CANCER Volume 103, 1457-1467
- K Fogel, Producing Open Source Software, First Edition, O'Reilly, 2005
- J Bloch, Effective Java, Second Edition, Sun Microsystems, 2008
-
- Other acknowledgements:
-
- CanReg1: Allen Bieber
- CanReg2: Stéphane Olivier
- CanReg3 and 4: Andy Cooke
-
- Licenses
- The RSSutils library
- is copyright 2003 Sun Microsystems, Inc. ALL RIGHTS RESERVED
- The Soundex library
- is copyright 1996-2002 Ian F. Darwin, http://www.darwinsys.com/, ALL RIGHTS RESERVED
-
+
+
+
+
+ CanReg5: About
+
+
+
+ Copyright
+ © 2008-2020
+ International Agency for Research on Cancer
World Health
+ Organization
All rights reserved. (Licensing information)
+ Credits
+ Lead developement and design:
+ Morten Johannes Ervik, IARC/CSU
+
+ Additional developement:
+ Andy Cooke (Original quality control module)
+ Jacques Ferlay (Original PostScript code and conversion tables)
+ Mathieu Laversanne (R code for analysis)
+ Sebastien Antoni (R code for analysis)
+ Anahita Rahimi (R code for analysis)
+ Hemant Dhivar (Migration Tool)
+ Betty Carballo and Patricio Carranza (New Dataentry form, bug fixes)
+
+ Additional design:
+ Andy Cooke
+ Maria Paula Curado
+ Lydia Voti, IARC/SCR
+ Freddie Bray
+ David Forman
+ Max Parkin
+
+ Consultants:
+ Philippe Autier, IARC/BIO
+ Hoda Anton-Culver, University of California Irvine, USA
+ Joe Harford, NCI, USA
+ Hai-Rim Shin, IARC/DEA
+ John Young, Emory University, USA
+
+ Technical consultants:
+ Michel Smans, IARC/ITS
+ Lucile Alteyrac, IARC/BIO
+
+ Thanks:
+ Kai Toedter (JCalendar)
+ Jeremy Dickson (CachingTableAPI)
+ Alexandre Moore (Icons)
+ Brian Cole (PagingTableModel)
+ Stephen Kelvin (XTableColumnModel)
+ Ashok Banerjee and Jignesh Mehta (ExcelAdapter)
+ Glen Smith et al (opencsv)
+ Dem Pilafian (Bare Bones Browser Launch)
+ Jesse Wilson (Glazed Lists)
+ Frank Tang (juniversalchardet)
+ Object REfinery Limited (JFreeChart)
+ Chris Evans (jcommons)
+ The Buzz Media (imgscalr – Java Image Scaling Library)
+ The Apache Software Foundation (Batik)
+ iText Software Corp (iText)
+
+ Testers:
+ Mathieu Mazuir, IARC/DEP
+ Antoine Buemi, Registre des Cancers du Haut-Rhin
+
+ Beta-testers:
+ Xenios Anastassiades, Ministry of Health, Cyprus
+ Deborah Bringman, University of California Irvine, USA
+ Amr Ebeid, Gharbiah Cancer Registry, Egypt
+ Ibrahim Abd-Elbar Seif Eldin, Gharbiah Cancer Registry, Egypt
+ Sarah Marshall, University of California Irvine, USA
+ Omar Nimri, Jordan Cancer Registry, Jordan
+ M. Ramadan, Gharbiah Cancer Registry, Egypt
+ Kevin Ward, Emory University, USA
+ Cankut Yakut, Izmir Cancer Registry, Turkey
+
+ Translators:
+ French: Joannie Lortet-Tieulent, IARC, France
+ Portugese: Edesio Martins, Goiania Cancer Registry, Brazil
+ Russian: Evgeniya Ostroumova, IARC, France and Anton Ryzhov, Ukraine
+ Spanish: Graciela Cristina Nicolas, Cordoba, Argentina
+ Chinese: Yayun Dai, IARC, France and Shixuan Liu, China
+ Portugese, Portugal: Gonçalo Lacerda, Azores, Portugal
+ Turkish: Cankut Yakut, Izmir Cancer Registry, Turkey
+
+ References:
+
+ J Ferlay et al, Check and Conversion Programs for Cancer Registries (IARC/IACR Tools for Cancer Registries), IARC Technical Report No. 42, Lyon, 2005 (Available at: http://www.iacr.com.fr/TR42.htm)
+ O.M. Jensen et al, Cancer Registration: Principles and Methods, IARC Scientific Publication No. 95, Lyon, 1991 (Available online at http://www.iarc.fr./en/publications/pdfs-online/epi/sp95/index.php)
+ E Steliarova-Foucher et al, Childhood Classification, Third Edition, CANCER Volume 103, 1457-1467
+ K Fogel, Producing Open Source Software, First Edition, O'Reilly, 2005
+ J Bloch, Effective Java, Second Edition, Sun Microsystems, 2008
+
+ Other acknowledgements:
+
+ CanReg1: Allen Bieber
+ CanReg2: Stéphane Olivier
+ CanReg3 and 4: Andy Cooke
+
+ Licenses
+ The RSSutils library
+ is copyright 2003 Sun Microsystems, Inc. ALL RIGHTS RESERVED
+ The Soundex library
+ is copyright 1996-2002 Ian F. Darwin, http://www.darwinsys.com/, ALL RIGHTS RESERVED
+
\ No newline at end of file
diff --git a/src/canreg/common/DateHelper.java b/src/canreg/common/DateHelper.java
index 1e328204..d775127a 100644
--- a/src/canreg/common/DateHelper.java
+++ b/src/canreg/common/DateHelper.java
@@ -1,263 +1,281 @@
-/**
- * CanReg5 - a tool to input, store, check and analyse cancer registry data.
- * Copyright (C) 2008-2019 International Agency for Research on Cancer
- *
- * 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 3 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see .
- *
- * @author Morten Johannes Ervik, CSU/IARC, ervikm@iarc.fr
- */
-package canreg.common;
-
-import java.text.DecimalFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- *
- * @author ervikm
- */
-public class DateHelper {
-
- public static GregorianCalendarCanReg parseDateStringToGregorianCalendarCanReg(String dateString, String dateFormatString) throws ParseException, IllegalArgumentException {
-
- if (dateString.length() != dateFormatString.length()) {
- return null;
- }
-
- boolean unknownDay = false;
- boolean unknownMonth = false;
- boolean unknownYear = false;
-
- int day = 99;
- int month = 99;
- int year = 9999;
-
- String yearString = getYear(dateString, dateFormatString);
- String monthString = getMonth(dateString, dateFormatString);
- String dayString = getDay(dateString, dateFormatString);
-
- if (dayString.trim().length() > 0) {
- day = Integer.parseInt(dayString);
- } else {
- day = 99;
- }
- if (monthString.trim().length() > 0) {
- month = Integer.parseInt(monthString);
- } else {
- month = 99;
-
- }
- if (yearString.trim().length() > 0) {
- year = Integer.parseInt(yearString);
-
- } else {
- year = 9999;
- }
-
- GregorianCalendarCanReg calendar = new GregorianCalendarCanReg();
-
- calendar.clear();
- calendar.setLenient(false);
- calendar.set(year, month - 1, day);
-
- boolean dateReadProperly = false;
-
- try {
- calendar.getTimeInMillis(); // This is just to trigger an error - if we have one latent...
- dateReadProperly = true;
- } catch (IllegalArgumentException iae) {
- if ("YEAR".equalsIgnoreCase(iae.getMessage())) {
- calendar.clear(Calendar.YEAR);
- calendar.setUnknownYearValue(yearString);
- // if this is what triggers the error set it to unknown
- unknownYear = true;
- } else if ("MONTH".equalsIgnoreCase(iae.getMessage()) || "MONTH: 1 -> 2".equalsIgnoreCase(iae.getMessage())) {
- calendar.clear(Calendar.MONTH);
- calendar.setUnknownMonthValue(monthString);
- // if this is what triggers the error set it to unknown
- unknownMonth = true;
- } else if ("DAY_OF_MONTH".equalsIgnoreCase(iae.getMessage())) {
- calendar.clear(Calendar.DAY_OF_MONTH);
- calendar.setUnknownDayValue(dayString);
- // if this is what triggers the error set it to unknown
- unknownDay = true;
- } else {
- throw iae;
- }
- }
-
- calendar.setUnknownDay(unknownDay);
- calendar.setUnkownMonth(unknownMonth);
- calendar.setUnknownYear(unknownYear);
-
- return calendar;
- }
-
- public static String parseGregorianCalendarCanRegToDateString(GregorianCalendarCanReg calendar, String dateFormatString) {
- String dateString = dateFormatString;
- DecimalFormat format = new DecimalFormat();
- // NumberFormatter nf = new NumberFormatter(format);
- format.setMinimumIntegerDigits(2);
- format.setGroupingUsed(false);
- try {
- if (calendar.isUnknownYear() || !calendar.isSet(Calendar.YEAR)) {
- dateString = setYear(dateString, dateFormatString, calendar.getUnknownYearValue() + "");
- } else {
- dateString = setYear(dateString, dateFormatString, format.format(calendar.get(Calendar.YEAR)));
- }
- if (calendar.isUnknownMonth() || !calendar.isSet(Calendar.MONTH)) {
- dateString = setMonth(dateString, dateFormatString, calendar.getUnknownMonthValue() + "");
- } else {
- dateString = setMonth(dateString, dateFormatString, format.format(calendar.get(Calendar.MONTH) + 1));
- }
- if (calendar.isUnknownDay() || !calendar.isSet(Calendar.DAY_OF_MONTH)) {
- dateString = setDay(dateString, dateFormatString, calendar.getUnknownDayValue() + "");
- } else {
- dateString = setDay(dateString, dateFormatString, format.format(calendar.get(Calendar.DAY_OF_MONTH)));
- }
- } catch (IllegalArgumentException iae) {
- System.out.println(iae + ": " + calendar);
- }
- return dateString;
- }
-
- public static String getYear(String dateString, String dateFormatString) {
- return getPartOfStringBasedOnFilter(dateString, dateFormatString, 'y');
- }
-
- public static String getMonth(String dateString, String dateFormatString) {
- return getPartOfStringBasedOnFilter(dateString, dateFormatString, 'm');
- }
-
- public static String getDay(String dateString, String dateFormatString) {
- return getPartOfStringBasedOnFilter(dateString, dateFormatString, 'd');
- }
-
- private static String getPartOfStringBasedOnFilter(String string, String filter, char lookFor) {
- String returnString = "";
-
- // Case insensitive
- filter = canreg.common.Tools.toLowerCaseStandardized(filter);
-
- for (int i = 0; i < string.length() && i < filter.length(); i++) {
- if (filter.charAt(i) == lookFor) {
- returnString += string.charAt(i);
- }
- }
- return returnString;
- }
-
- public static String setYear(String dateString, String dateFormatString, String replacementString) {
- return setPartOfStringBasedOnFilter(dateString, dateFormatString, 'y', replacementString);
- }
-
- public static String setMonth(String dateString, String dateFormatString, String replacementString) {
- return setPartOfStringBasedOnFilter(dateString, dateFormatString, 'm', replacementString);
- }
-
- public static String setDay(String dateString, String dateFormatString, String replacementString) {
- return setPartOfStringBasedOnFilter(dateString, dateFormatString, 'd', replacementString);
- }
-
- private static String setPartOfStringBasedOnFilter(String string, String filter, char lookFor, String replacementString) {
- // Case insensitive
- String newString = "";
- filter = canreg.common.Tools.toLowerCaseStandardized(filter);
- int placeInReplacementString = 0;
- for (int i = 0; i < string.length() && i < filter.length(); i++) {
- if (filter.charAt(filter.length() - 1 - i) == lookFor) {
- newString = replacementString.charAt(replacementString.length() - 1 - placeInReplacementString++) + newString;
- if (placeInReplacementString >= replacementString.length()) {
- placeInReplacementString = 0;
- }
- } else {
- newString = string.charAt(string.length() - 1 - i) + newString;
- }
- }
- return newString;
- }
-
- public static long daysBetween(GregorianCalendarCanReg startDate, GregorianCalendarCanReg endDate) {
- int sign = 1;
- if (startDate.after(endDate)){
- GregorianCalendarCanReg tempDate = startDate;
- startDate = endDate;
- endDate = tempDate;
- sign = -1;
- }
- GregorianCalendarCanReg date = (GregorianCalendarCanReg) startDate.clone();
- long daysBetween = 0;
- while (date.compareTo(endDate)<=0) {
- date.add(Calendar.DAY_OF_MONTH, 1);
- daysBetween++;
- }
- return sign * (daysBetween - 1);
- }
-
- public static long yearsBetween(GregorianCalendarCanReg startDate, GregorianCalendarCanReg endDate) {
- startDate = correctUnknown(startDate);
- endDate = correctUnknown(endDate);
-
- int sign = 1;
- if (startDate.after(endDate)){
- GregorianCalendarCanReg tempDate = startDate;
- startDate = endDate;
- endDate = tempDate;
- sign = -1;
- }
-
- GregorianCalendarCanReg date = startDate.clone();
- long yearsBetween = 0;
- while (date.compareTo(endDate)<=0) {
- date.add(Calendar.YEAR, 1);
- yearsBetween++;
- }
- return (yearsBetween -1) * sign;
- }
-
- public static GregorianCalendarCanReg correctUnknown(GregorianCalendarCanReg date) {
- GregorianCalendarCanReg newDate = date.clone();
- // for calculations "correct unknown"
- if (date.isUnknownMonth()) {
- // Set month to July
- date.set(Calendar.MONTH, 7 - 1);
- date.setUnkownMonth(false);
- // And day to first
- date.set(Calendar.DAY_OF_MONTH, 1);
- date.setUnknownDay(false);
- } else if (date.isUnknownDay()) {
- // Set day to mid-month
- date.set(Calendar.DAY_OF_MONTH, 15);
- date.setUnknownDay(false);
- }
- return date;
- }
-
- public static Calendar parseTimestamp(String timestamp, String dateFormat, Locale locale) throws ParseException {
- /*
- ** we specify Locale.US since months are in english
- */
- if (locale == null) {
- locale = Locale.getDefault();
- }
- SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);
- Date d = sdf.parse(timestamp);
- Calendar cal = Calendar.getInstance();
- cal.setTime(d);
- return cal;
- }
-}
+/**
+ * CanReg5 - a tool to input, store, check and analyse cancer registry data.
+ * Copyright (C) 2008-2019 International Agency for Research on Cancer
+ *
+ * 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ *
+ * @author Morten Johannes Ervik, CSU/IARC, ervikm@iarc.fr
+ */
+package canreg.common;
+
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ *
+ * @author ervikm
+ */
+public class DateHelper {
+
+ public static GregorianCalendarCanReg parseDateStringToGregorianCalendarCanReg(String dateString, String dateFormatString) throws ParseException, IllegalArgumentException {
+
+ if (dateString.length() != dateFormatString.length()) {
+ return null;
+ }
+
+ boolean unknownDay = false;
+ boolean unknownMonth = false;
+ boolean unknownYear = false;
+
+ int day = 99;
+ int month = 99;
+ int year = 9999;
+
+ String yearString = getYear(dateString, dateFormatString);
+ String monthString = getMonth(dateString, dateFormatString);
+ String dayString = getDay(dateString, dateFormatString);
+
+ if (dayString.trim().length() > 0) {
+ day = Integer.parseInt(dayString);
+ } else {
+ day = 99;
+ }
+ if (monthString.trim().length() > 0) {
+ month = Integer.parseInt(monthString);
+ } else {
+ month = 99;
+
+ }
+ if (yearString.trim().length() > 0) {
+ year = Integer.parseInt(yearString);
+
+ } else {
+ year = 9999;
+ }
+
+ GregorianCalendarCanReg calendar = new GregorianCalendarCanReg();
+
+ calendar.clear();
+ calendar.setLenient(false);
+ calendar.set(year, month - 1, day);
+
+ boolean dateReadProperly = false;
+
+ if (year == 9999) {
+ calendar.clear(Calendar.YEAR);
+ calendar.setUnknownYearValue(yearString);
+ unknownYear = true;
+ }
+ if (month == 99 || month == 0) {
+ calendar.clear(Calendar.MONTH);
+ calendar.setUnknownMonthValue(monthString);
+ unknownMonth = true;
+ }
+ if (day == 99 || day == 00 ) {
+ calendar.clear(Calendar.DAY_OF_MONTH);
+ calendar.setUnknownDayValue(dayString);
+ // if this is what triggers the error set it to unknown
+ unknownDay = true;
+ }
+
+// This approach only detects the first unknown, so not enough...
+// try {
+// calendar.getTimeInMillis(); // This is just to trigger an error - if we have one latent...
+// dateReadProperly = true;
+// } catch (IllegalArgumentException iae) {
+// if ("YEAR".equalsIgnoreCase(iae.getMessage())) {
+// calendar.clear(Calendar.YEAR);
+// calendar.setUnknownYearValue(yearString);
+// // if this is what triggers the error set it to unknown
+// unknownYear = true;
+// } else if ("MONTH".equalsIgnoreCase(iae.getMessage()) || "MONTH: 1 -> 2".equalsIgnoreCase(iae.getMessage())) {
+// calendar.clear(Calendar.MONTH);
+// calendar.setUnknownMonthValue(monthString);
+// // if this is what triggers the error set it to unknown
+// unknownMonth = true;
+// } else if ("DAY_OF_MONTH".equalsIgnoreCase(iae.getMessage())) {
+// calendar.clear(Calendar.DAY_OF_MONTH);
+// calendar.setUnknownDayValue(dayString);
+// // if this is what triggers the error set it to unknown
+// unknownDay = true;
+// } else {
+// throw iae;
+// }
+// }
+
+ calendar.setUnknownDay(unknownDay);
+ calendar.setUnkownMonth(unknownMonth);
+ calendar.setUnknownYear(unknownYear);
+
+ return calendar;
+ }
+
+ public static String parseGregorianCalendarCanRegToDateString(GregorianCalendarCanReg calendar, String dateFormatString) {
+ String dateString = dateFormatString;
+ DecimalFormat format = new DecimalFormat();
+ // NumberFormatter nf = new NumberFormatter(format);
+ format.setMinimumIntegerDigits(2);
+ format.setGroupingUsed(false);
+ try {
+ if (calendar.isUnknownYear() || !calendar.isSet(Calendar.YEAR)) {
+ dateString = setYear(dateString, dateFormatString, calendar.getUnknownYearValue() + "");
+ } else {
+ dateString = setYear(dateString, dateFormatString, format.format(calendar.get(Calendar.YEAR)));
+ }
+ if (calendar.isUnknownMonth() || !calendar.isSet(Calendar.MONTH)) {
+ dateString = setMonth(dateString, dateFormatString, calendar.getUnknownMonthValue() + "");
+ } else {
+ dateString = setMonth(dateString, dateFormatString, format.format(calendar.get(Calendar.MONTH) + 1));
+ }
+ if (calendar.isUnknownDay() || !calendar.isSet(Calendar.DAY_OF_MONTH)) {
+ dateString = setDay(dateString, dateFormatString, calendar.getUnknownDayValue() + "");
+ } else {
+ dateString = setDay(dateString, dateFormatString, format.format(calendar.get(Calendar.DAY_OF_MONTH)));
+ }
+ } catch (IllegalArgumentException iae) {
+ System.out.println(iae + ": " + calendar);
+ }
+ return dateString;
+ }
+
+ public static String getYear(String dateString, String dateFormatString) {
+ return getPartOfStringBasedOnFilter(dateString, dateFormatString, 'y');
+ }
+
+ public static String getMonth(String dateString, String dateFormatString) {
+ return getPartOfStringBasedOnFilter(dateString, dateFormatString, 'm');
+ }
+
+ public static String getDay(String dateString, String dateFormatString) {
+ return getPartOfStringBasedOnFilter(dateString, dateFormatString, 'd');
+ }
+
+ private static String getPartOfStringBasedOnFilter(String string, String filter, char lookFor) {
+ String returnString = "";
+
+ // Case insensitive
+ filter = canreg.common.Tools.toLowerCaseStandardized(filter);
+
+ for (int i = 0; i < string.length() && i < filter.length(); i++) {
+ if (filter.charAt(i) == lookFor) {
+ returnString += string.charAt(i);
+ }
+ }
+ return returnString;
+ }
+
+ public static String setYear(String dateString, String dateFormatString, String replacementString) {
+ return setPartOfStringBasedOnFilter(dateString, dateFormatString, 'y', replacementString);
+ }
+
+ public static String setMonth(String dateString, String dateFormatString, String replacementString) {
+ return setPartOfStringBasedOnFilter(dateString, dateFormatString, 'm', replacementString);
+ }
+
+ public static String setDay(String dateString, String dateFormatString, String replacementString) {
+ return setPartOfStringBasedOnFilter(dateString, dateFormatString, 'd', replacementString);
+ }
+
+ private static String setPartOfStringBasedOnFilter(String string, String filter, char lookFor, String replacementString) {
+ // Case insensitive
+ String newString = "";
+ filter = canreg.common.Tools.toLowerCaseStandardized(filter);
+ int placeInReplacementString = 0;
+ for (int i = 0; i < string.length() && i < filter.length(); i++) {
+ if (filter.charAt(filter.length() - 1 - i) == lookFor) {
+ newString = replacementString.charAt(replacementString.length() - 1 - placeInReplacementString++) + newString;
+ if (placeInReplacementString >= replacementString.length()) {
+ placeInReplacementString = 0;
+ }
+ } else {
+ newString = string.charAt(string.length() - 1 - i) + newString;
+ }
+ }
+ return newString;
+ }
+
+ public static long daysBetween(GregorianCalendarCanReg startDate, GregorianCalendarCanReg endDate) {
+ int sign = 1;
+ if (startDate.after(endDate)){
+ GregorianCalendarCanReg tempDate = startDate;
+ startDate = endDate;
+ endDate = tempDate;
+ sign = -1;
+ }
+ GregorianCalendarCanReg date = (GregorianCalendarCanReg) startDate.clone();
+ long daysBetween = 0;
+ while (date.compareTo(endDate)<=0) {
+ date.add(Calendar.DAY_OF_MONTH, 1);
+ daysBetween++;
+ }
+ return sign * (daysBetween - 1);
+ }
+
+ public static long yearsBetween(GregorianCalendarCanReg startDate, GregorianCalendarCanReg endDate) {
+ startDate = correctUnknown(startDate);
+ endDate = correctUnknown(endDate);
+
+ int sign = 1;
+ if (startDate.after(endDate)){
+ GregorianCalendarCanReg tempDate = startDate;
+ startDate = endDate;
+ endDate = tempDate;
+ sign = -1;
+ }
+
+ GregorianCalendarCanReg date = startDate.clone();
+ long yearsBetween = 0;
+ while (date.compareTo(endDate)<=0) {
+ date.add(Calendar.YEAR, 1);
+ yearsBetween++;
+ }
+ return (yearsBetween -1) * sign;
+ }
+
+ public static GregorianCalendarCanReg correctUnknown(GregorianCalendarCanReg date) {
+ GregorianCalendarCanReg newDate = date.clone();
+ // for calculations "correct unknown"
+ if (date.isUnknownMonth()) {
+ // Set month to July
+ date.set(Calendar.MONTH, 7 - 1);
+ date.setUnkownMonth(false);
+ // And day to first
+ date.set(Calendar.DAY_OF_MONTH, 1);
+ date.setUnknownDay(false);
+ } else if (date.isUnknownDay()) {
+ // Set day to mid-month
+ date.set(Calendar.DAY_OF_MONTH, 15);
+ date.setUnknownDay(false);
+ }
+ return date;
+ }
+
+ public static Calendar parseTimestamp(String timestamp, String dateFormat, Locale locale) throws ParseException {
+ /*
+ ** we specify Locale.US since months are in english
+ */
+ if (locale == null) {
+ locale = Locale.getDefault();
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);
+ Date d = sdf.parse(timestamp);
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(d);
+ return cal;
+ }
+}
diff --git a/src/canreg/common/resources/dictionaries/grade.tsv b/src/canreg/common/resources/dictionaries/grade.tsv
new file mode 100644
index 00000000..3f9f2d07
--- /dev/null
+++ b/src/canreg/common/resources/dictionaries/grade.tsv
@@ -0,0 +1,9 @@
+1 Grade I
+2 Grade II
+3 Grade III
+4 Grade IV
+5 T-Cell
+6 B-Cell
+7 Null cell
+8 NK cell
+9 Unknown/Not Stated/NA
\ No newline at end of file
diff --git a/src/canreg/server/database/CanRegDAO.java b/src/canreg/server/database/CanRegDAO.java
index 64b2b2ce..1ac8dce5 100644
--- a/src/canreg/server/database/CanRegDAO.java
+++ b/src/canreg/server/database/CanRegDAO.java
@@ -1,6 +1,6 @@
/**
* CanReg5 - a tool to input, store, check and analyse cancer registry data.
- * Copyright (C) 2008-2017 International Agency for Research on Cancer
+ * Copyright (C) 2008-2020 International Agency for Research on Cancer
*
* 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
@@ -1538,6 +1538,12 @@ private synchronized boolean fillDictionariesTable() {
} catch (IOException ex) {
Logger.getLogger(CanRegDAO.class.getName()).log(Level.SEVERE, null, ex);
}
+ // Behaviour
+ try {
+ fillDictionary(Globals.StandardVariableNames.Grade, Globals.DEFAULT_DICTIONARIES_FOLDER + "/grade.tsv");
+ } catch (IOException ex) {
+ Logger.getLogger(CanRegDAO.class.getName()).log(Level.SEVERE, null, ex);
+ }
// Basis
try {
fillDictionary(Globals.StandardVariableNames.BasisDiagnosis, Globals.DEFAULT_DICTIONARIES_FOLDER + "/basis.tsv");
@@ -1558,7 +1564,7 @@ private synchronized boolean fillDictionariesTable() {
private synchronized static Map buildDictionaryMap(Document doc) {
- Map dictionariesMap = new LinkedHashMap();
+ Map dictionariesMap = new LinkedHashMap();
// NodeList dictionaries = variablesElement.getElementsByTagName(Globals.NAMESPACE + "dictionary");
DatabaseDictionaryListElement[] dictionaries = canreg.common.Tools.getDictionaryListElements(doc, Globals.NAMESPACE);
diff --git a/version.txt b/version.txt
index 78dce093..e85bccc0 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-5.00.44b
+5.00.44c