Skip to content

Commit

Permalink
Merge pull request #502 from keithc-ca/date
Browse files Browse the repository at this point in the history
Avoid non-portable uses of date utility
  • Loading branch information
pshipton authored Oct 6, 2022
2 parents 1968f88 + 875e7d1 commit 51911e3
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 40 deletions.
6 changes: 5 additions & 1 deletion make/InitSupport.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
# questions.
#

# ===========================================================================
# (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
# ===========================================================================

################################################################################
# This file contains helper functions for Init.gmk.
# It is divided in two parts, depending on if a SPEC is present or not
Expand Down Expand Up @@ -311,7 +315,7 @@ else # $(HAS_SPEC)=true
define SetupReproducibleBuild
ifeq ($$(SOURCE_DATE), updated)
# For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk
export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s")
export SOURCE_DATE_EPOCH := $$(shell $$(JAVA) $$(TOPDIR)/make/src/classes/DateUtil.java)
export SOURCE_DATE_ISO_8601 := $$(call EpochToISO8601, $$(SOURCE_DATE_EPOCH))
endif
endef
Expand Down
20 changes: 8 additions & 12 deletions make/autoconf/jdk-options.m4
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
# questions.
#

# ===========================================================================
# (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
# ===========================================================================

###############################################################################
# Set the debug level
# release: no debug information, all optimizations, no asserts.
Expand Down Expand Up @@ -203,13 +207,9 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS],
elif test "x$with_copyright_year" != x; then
COPYRIGHT_YEAR="$with_copyright_year"
elif test "x$SOURCE_DATE" != xupdated; then
if test "x$IS_GNU_DATE" = xyes; then
COPYRIGHT_YEAR=`$DATE --date=@$SOURCE_DATE +%Y`
else
COPYRIGHT_YEAR=`$DATE -j -f %s $SOURCE_DATE +%Y`
fi
COPYRIGHT_YEAR=`$JAVA $TOPDIR/make/src/classes/DateUtil.java --format=yyyy --date="$SOURCE_DATE_EPOCH"`
else
COPYRIGHT_YEAR=`$DATE +'%Y'`
COPYRIGHT_YEAR=`$JAVA $TOPDIR/make/src/classes/DateUtil.java --format=yyyy`
fi
AC_SUBST(COPYRIGHT_YEAR)
Expand Down Expand Up @@ -676,7 +676,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_REPRODUCIBLE_BUILD],
AC_MSG_RESULT([determined at build time, from 'updated'])
elif test "x$with_source_date" = xcurrent; then
# Set the current time
SOURCE_DATE=$($DATE +"%s")
SOURCE_DATE=$($JAVA $TOPDIR/make/src/classes/DateUtil.java)
AC_MSG_RESULT([$SOURCE_DATE, from 'current'])
elif test "x$with_source_date" = xversion; then
# Use the date from version-numbers.conf
Expand Down Expand Up @@ -708,11 +708,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_REPRODUCIBLE_BUILD],
# If we have a fixed value for SOURCE_DATE, we need to set SOURCE_DATE_EPOCH
# for the rest of configure.
SOURCE_DATE_EPOCH="$SOURCE_DATE"
if test "x$IS_GNU_DATE" = xyes; then
SOURCE_DATE_ISO_8601=`$DATE --utc --date="@$SOURCE_DATE" +"$ISO_8601_FORMAT_STRING" 2> /dev/null`
else
SOURCE_DATE_ISO_8601=`$DATE -u -j -f "%s" "$SOURCE_DATE" +"$ISO_8601_FORMAT_STRING" 2> /dev/null`
fi
SOURCE_DATE_ISO_8601=`$JAVA $TOPDIR/make/src/classes/DateUtil.java --date="$SOURCE_DATE" --format="yyyy-MM-dd'T'HH:mm:ss'Z'"`
fi
AC_SUBST(SOURCE_DATE)
Expand Down
23 changes: 5 additions & 18 deletions make/autoconf/util.m4
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
# questions.
#

# ===========================================================================
# (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
# ===========================================================================

m4_include([util_paths.m4])

###############################################################################
Expand Down Expand Up @@ -234,24 +238,7 @@ AC_DEFUN([UTIL_GET_MATCHING_VALUES],
# $2: input date/time string
AC_DEFUN([UTIL_GET_EPOCH_TIMESTAMP],
[
if test "x$IS_GNU_DATE" = xyes; then
# GNU date
timestamp=$($DATE --utc --date=$2 +"%s" 2> /dev/null)
else
# BSD date
# ISO-8601 date&time in Zulu 'date'T'time'Z
timestamp=$($DATE -u -j -f "%FT%TZ" "$2" "+%s" 2> /dev/null)
if test "x$timestamp" = x; then
# BSD date cannot handle trailing milliseconds.
# Try again ignoring characters at end
timestamp=$($DATE -u -j -f "%Y-%m-%dT%H:%M:%S" "$2" "+%s" 2> /dev/null)
fi
if test "x$timestamp" = x; then
# Perhaps the time was missing.
timestamp=$($DATE -u -j -f "%FT%TZ" "$2""T00:00:00Z" "+%s" 2> /dev/null)
fi
fi
$1=$timestamp
$1=$($JAVA $TOPDIR/make/src/classes/DateUtil.java --date="$2")
])

###############################################################################
Expand Down
14 changes: 5 additions & 9 deletions make/common/Utils.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
# questions.
#

# ===========================================================================
# (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
# ===========================================================================

ifeq (,$(_MAKEBASE_GMK))
$(error You must include MakeBase.gmk prior to including Utils.gmk)
endif
Expand Down Expand Up @@ -227,15 +231,7 @@ Or = \
# Convert an UNIX epoch based timestamp (as an integer) to an ISO 8601 date
# string.
# Param 1 - timestamp
ifeq ($(IS_GNU_DATE), yes)
EpochToISO8601 = \
$(shell $(DATE) --utc --date="@$(strip $1)" \
+"$(ISO_8601_FORMAT_STRING)" 2> /dev/null)
else
EpochToISO8601 = \
$(shell $(DATE) -u -j -f "%s" "$(strip $1)" \
+"$(ISO_8601_FORMAT_STRING)" 2> /dev/null)
endif
EpochToISO8601 = $(shell $(JAVA) $(TOPDIR)/make/src/classes/DateUtil.java --date="$(strip $1)" --format="yyyy-MM-dd'T'HH:mm:ss'Z'")

################################################################################
# Parse a multiple-keyword variable, like FOO="KEYWORD1=val1;KEYWORD2=val2;..."
Expand Down
94 changes: 94 additions & 0 deletions make/src/classes/DateUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* ===========================================================================
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* IBM designates this particular file as subject to the "Classpath" exception
* as provided by IBM in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
* ===========================================================================
*/
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;

public class DateUtil {

public static void main(String... args) {
String date = "";
String format = "";

for (String arg : args) {
if (arg.startsWith("--date=")) {
date = arg.substring(7).trim();
} else if (arg.startsWith("--format=")) {
format = arg.substring(9).trim();
} else {
showUsageAndExit();
}
}

LocalDateTime time = parseTime(date);

if (format.isEmpty()) {
System.out.println(time.toEpochSecond(ZoneOffset.UTC));
} else {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format, Locale.ROOT);

System.out.println(formatter.format(time));
}
}

private static LocalDateTime parseTime(String text) {
if (text.isEmpty()) {
return LocalDateTime.now(ZoneOffset.UTC);
}

if (text.matches("\\d+")) {
return LocalDateTime.ofEpochSecond(Long.parseLong(text), 0, ZoneOffset.UTC);
}

try {
return LocalDateTime.ofInstant(Instant.parse(text), ZoneOffset.UTC);
} catch (DateTimeParseException e) {
// try next format
}

try {
return LocalDateTime.parse(text);
} catch (DateTimeParseException e) {
// try next format
}

try {
return LocalDate.parse(text).atStartOfDay();
} catch (DateTimeParseException e) {
System.err.format("Cannot parse time: '%s'%n", text);
System.exit(1);
return null;
}
}

private static void showUsageAndExit() {
System.err.println("Usage: DateUtil [options]");
System.err.println(" --date=<time> time in epoch seconds, or in iso-8601 or yyyy-MM-dd format");
System.err.println(" --format=<format> output format");
System.exit(1);
}

}

0 comments on commit 51911e3

Please sign in to comment.