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