use of java.time.temporal.Temporal in project knime-core by knime.
the class CreateDateTimeNodeModel method createByFixedRowNrAndEnd.
/**
* Create date&time row with a fixed number of rows and a given starting point ending point.
*/
private void createByFixedRowNrAndEnd(final BufferedDataContainer container, final long nrRows, final Temporal startDateTime, final Temporal endDateTime) {
Temporal start = startDateTime;
Temporal end = endDateTime;
// if start or end time contains millis, remember this to create the output accordingly
final boolean hasMillis = hasMillis(start, end);
// because a period cannot be divided, convert a local date temporarily to a local date time
final boolean wasLocalDate = start instanceof LocalDate;
if (wasLocalDate) {
start = LocalDateTime.of((LocalDate) start, LocalTime.ofNanoOfDay(0));
end = LocalDateTime.of((LocalDate) end, LocalTime.ofNanoOfDay(0));
}
// === create all rows except the last one ===
if (nrRows > 1) {
final Duration durationInterval = Duration.between(start, end).dividedBy(nrRows - 1);
createByFixedRowNrAndDuration(container, nrRows - 1, start, durationInterval, wasLocalDate, hasMillis);
} else {
end = start;
}
// === last row needs to be end date&time ===
final DataCell dataCell;
if (end instanceof LocalTime) {
dataCell = LocalTimeCellFactory.create(hasMillis ? ((LocalTime) end).truncatedTo(ChronoUnit.MILLIS) : ((LocalTime) end).withNano(0));
} else if (end instanceof LocalDateTime) {
if (wasLocalDate) {
dataCell = LocalDateCellFactory.create(((LocalDateTime) end).toLocalDate());
} else {
dataCell = LocalDateTimeCellFactory.create(hasMillis ? ((LocalDateTime) end).truncatedTo(ChronoUnit.MILLIS) : ((LocalDateTime) end).withNano(0));
}
} else {
dataCell = ZonedDateTimeCellFactory.create(hasMillis ? ((ZonedDateTime) end).truncatedTo(ChronoUnit.MILLIS) : ((ZonedDateTime) end).withNano(0));
}
container.addRowToTable(new DefaultRow(new RowKey("Row" + (nrRows - 1)), dataCell));
}
use of java.time.temporal.Temporal in project knime-core by knime.
the class DateTimeDifferenceNodeModel method calculateTime.
private DataCell calculateTime(final DataCell cell, final DataCell referenceCell, final ZonedDateTime fixedDateTime) {
if (cell.isMissing()) {
return new MissingCell("Cell for calculating difference is missing.");
} else if (fixedDateTime == null && referenceCell.isMissing()) {
return new MissingCell("Reference cell for calculating difference is missing.");
}
final Temporal temporal1;
final Temporal temporal2;
if (cell instanceof ZonedDateTimeValue) {
temporal1 = ((ZonedDateTimeValue) cell).getZonedDateTime();
temporal2 = fixedDateTime == null ? ((ZonedDateTimeValue) referenceCell).getZonedDateTime() : fixedDateTime;
} else if (cell instanceof LocalDateTimeValue) {
temporal1 = ((LocalDateTimeValue) cell).getLocalDateTime();
temporal2 = fixedDateTime == null ? ((LocalDateTimeValue) referenceCell).getLocalDateTime() : fixedDateTime.toLocalDateTime();
} else {
temporal1 = ((LocalTimeValue) cell).getLocalTime();
temporal2 = fixedDateTime == null ? ((LocalTimeValue) referenceCell).getLocalTime() : fixedDateTime.toLocalTime();
}
if (m_calculationSelectModel.getStringValue().equals(OutputMode.Duration.name())) {
final Duration diffDuration = Duration.between(temporal1, temporal2);
return DurationCellFactory.create(diffDuration);
} else {
final Granularity granularity = Granularity.fromString(m_granularityModel.getStringValue());
return LongCellFactory.create(granularity.between(temporal1, temporal2));
}
}
use of java.time.temporal.Temporal in project knime-core by knime.
the class DateTimeBasedRowFilterNodeModel method calculateEndDateTime.
/**
* Calculates the ending point if period/duration or granularity is selected. Otherwise output will be the same as
* input (endDateTime).
*
* @param startDateTime starting point
* @param endDateTime current ending point
* @return
*/
private Temporal calculateEndDateTime(final Temporal startDateTime, final Temporal endDateTime) throws ArithmeticException, DateTimeException {
Temporal end = endDateTime;
if (m_endSelection.getStringValue().equals(EndMode.Duration.name())) {
try {
end = startDateTime.plus(DurationPeriodFormatUtils.parsePeriod(m_periodValueModel.getStringValue()));
} catch (DateTimeException e1) {
end = startDateTime.plus(DurationPeriodFormatUtils.parseDuration(m_periodValueModel.getStringValue()));
}
}
if (m_endSelection.getStringValue().equals(EndMode.Numerical.name())) {
final TemporalAmount amount = Granularity.fromString(m_granularityModel.getStringValue()).getPeriodOrDuration(m_numericalValueModel.getIntValue());
end = startDateTime.plus(amount);
}
return end;
}
use of java.time.temporal.Temporal in project knime-core by knime.
the class LoopStartWindowNodeModel method configure.
/**
* {@inheritDoc}
*/
@Override
protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException {
if (m_windowConfig == null) {
m_windowConfig = new LoopStartWindowConfiguration();
setWarningMessage("Using default: " + m_windowConfig);
}
DataTableSpec tableSpec = inSpecs[0];
if (m_windowConfig.getTrigger() == Trigger.TIME) {
if (!tableSpec.containsName(m_timeColumnName)) {
throw new InvalidSettingsException("Selected time column '" + m_timeColumnName + "' does not exist in input table.");
}
DataColumnSpec columnSpec = tableSpec.getColumnSpec(m_timeColumnName);
/* Check if the cells have the same type as the specified start time. */
if (m_windowConfig.useSpecifiedStartTime()) {
Temporal specifiedStartTime = m_timeConfig.getSelectedDateTime();
if (specifiedStartTime == null) {
throw new InvalidSettingsException("Specified start time is not compatible with selected time column '" + m_timeColumnName + "'");
}
}
/* Check if period is set for LocalTime */
TemporalAmount start = getTemporalAmount(m_windowConfig.getTimeStepSize() + m_windowConfig.getTimeStepUnit().getUnitLetter());
if (m_windowConfig.getTimeStepSize() == null) {
throw new InvalidSettingsException("No temporal step size set.");
}
if (start == null) {
throw new InvalidSettingsException("Given step size couldn't be matched to type Duration or Period.");
} else if (start instanceof Period && columnSpec.getType().equals(DataType.getType(LocalTimeCell.class))) {
throw new InvalidSettingsException("Step size: Period type not allowed for LocalTime");
}
TemporalAmount window = getTemporalAmount(m_windowConfig.getTimeWindowSize() + m_windowConfig.getTimeWindowUnit().getUnitLetter());
if (m_windowConfig.getTimeWindowSize() == null) {
throw new InvalidSettingsException("No window size set.");
}
if (window == null) {
throw new InvalidSettingsException("Given window size couldn't be machted to type Duration or Period.");
} else if (start instanceof Period && columnSpec.getType().equals(DataType.getType(LocalTimeCell.class))) {
throw new InvalidSettingsException("Window size: Period type not allowed for LocalTime");
}
}
return inSpecs;
}
use of java.time.temporal.Temporal in project knime-core by knime.
the class LoopStartWindowNodeModel method executeTemporalBackward.
/**
* Computes the next window that shall be returned for time triggered events using backward windowing.
*
* @param table that holds the data.
* @param exec context of the execution.
* @return Next window.
*/
private BufferedDataTable[] executeTemporalBackward(final BufferedDataTable table, final ExecutionContext exec) {
BufferedDataContainer container = exec.createDataContainer(table.getSpec());
int column = table.getDataTableSpec().findColumnIndex(m_timeColumnName);
TemporalAmount startInterval = getTemporalAmount(m_windowConfig.getTimeStepSize() + m_windowConfig.getTimeStepUnit().getUnitLetter());
TemporalAmount windowDuration = getTemporalAmount(m_windowConfig.getTimeWindowSize() + m_windowConfig.getTimeStepUnit().getUnitLetter());
/* To check if an overflow occurred concerning the current window */
boolean overflow = false;
// To check if an overflow occurred concerning next starting temporal.
m_lastWindow = false;
/* Compute end duration of window and beginning of next duration*/
if (m_nextStartTemporal == null && m_rowIterator.hasNext()) {
DataRow first = m_rowIterator.next();
/* Check if column only consists of missing values. */
while (first.getCell(column).isMissing() && m_rowIterator.hasNext()) {
first = m_rowIterator.next();
printMissingWarning();
}
if (first.getCell(column).isMissing()) {
m_logger.warn("Column '" + m_timeColumnName + "' only contains missing values.");
container.close();
return new BufferedDataTable[] { container.getTable() };
}
/* First entry is the end of the window. Compute next starting point by adding start interval minus the size of the window. */
Temporal firstEnd = getTemporal(first.getCell(column));
m_prevTemporal = firstEnd;
/* Check if user specified start shall be used. */
if (m_windowConfig.useSpecifiedStartTime()) {
firstEnd = m_timeConfig.getSelectedDateTime();
/* Move the window until the current end is greater or equal than the first row. */
while (compareTemporal(getTemporal(first.getCell(column)), firstEnd) > 0) {
Temporal tempNextEnd = firstEnd.plus(startInterval);
/* Check if next window yields an overflow. In this case we return an empty table. */
if (compareTemporal(tempNextEnd, firstEnd) <= 0) {
container.close();
m_logger.warn("No row lies within any of the possible windows.");
return new BufferedDataTable[] { container.getTable() };
}
firstEnd = tempNextEnd;
}
/* Current start temporal, m_nextStartTemporal is used to re-use the skipTemporalWindow method. */
m_nextStartTemporal = firstEnd.minus(windowDuration);
m_windowEndTemporal = firstEnd;
/* Check for underflow of the current start. */
if (compareTemporal(m_nextStartTemporal, firstEnd) >= 0) {
m_nextStartTemporal = getMin(m_nextStartTemporal);
m_bufferedRows.add(first);
} else {
/* Skip window until we find one which contains at least one row. */
skipTemporalWindow(first, column, startInterval, windowDuration);
firstEnd = m_nextStartTemporal.plus(windowDuration);
/* Check if overflow of window occurred. In this case we return an empty table. */
if (compareTemporal(firstEnd, m_nextStartTemporal) <= 0) {
container.close();
m_logger.warn("No row lies within any of the possible windows.");
return new BufferedDataTable[] { container.getTable() };
}
/* This fixes a bug (AP-8975) in the case where we only have to skip one window as the first applicable row lies within the
* next window. In this case the skipTemporalWindow simply returns without any changes. */
Temporal temp = firstEnd.plus(startInterval);
if (!m_bufferedRows.isEmpty() && compareTemporal(firstEnd, getTemporal(m_bufferedRows.getFirst().getCell(column))) < 0 && (compareTemporal(temp, temp.minus(windowDuration)) < 0 || compareTemporal(temp.minus(windowDuration), getTemporal(m_bufferedRows.getFirst().getCell(column))) < 0)) {
firstEnd = firstEnd.plus(startInterval);
}
}
/* Check if we found a window which contains at least one row. */
if (m_bufferedRows.isEmpty()) {
container.close();
m_logger.warn("No row lies within any of the possible windows.");
return new BufferedDataTable[] { container.getTable() };
}
}
m_windowEndTemporal = firstEnd;
m_prevTemporal = getTemporal(first.getCell(column));
if (!m_windowConfig.useSpecifiedStartTime()) {
m_bufferedRows.add(first);
}
Temporal tempNextEnd = m_windowEndTemporal.plus(startInterval);
/* Check if the current window is the last window. */
if (compareTemporal(tempNextEnd, m_windowEndTemporal) <= 0) {
m_lastWindow = true;
} else {
m_nextStartTemporal = tempNextEnd.minus(windowDuration);
if (compareTemporal(m_nextStartTemporal, tempNextEnd) >= 0) {
m_nextStartTemporal = getMin(tempNextEnd);
}
}
} else {
Temporal tempNextEnd = m_windowEndTemporal.plus(startInterval);
/* Check if the current window is the last window. */
if (compareTemporal(tempNextEnd, m_windowEndTemporal) <= 0) {
m_lastWindow = true;
} else {
m_nextStartTemporal = tempNextEnd.minus(windowDuration).plus(startInterval);
if (compareTemporal(m_nextStartTemporal, tempNextEnd) >= 0) {
m_nextStartTemporal = getMin(tempNextEnd);
}
}
m_windowEndTemporal = tempNextEnd;
}
Temporal tempNextEnd = m_windowEndTemporal.plus(startInterval);
/* Check if the current window is the last window. */
if (compareTemporal(tempNextEnd, m_windowEndTemporal) <= 0) {
m_lastWindow = true;
} else {
m_nextStartTemporal = tempNextEnd.minus(windowDuration);
if (compareTemporal(m_nextStartTemporal, tempNextEnd) >= 0) {
m_nextStartTemporal = getMin(tempNextEnd);
}
}
Iterator<DataRow> bufferedIterator = m_bufferedRows.iterator();
boolean allBufferedRowsInWindow = true;
/* Add buffered rows. */
while (bufferedIterator.hasNext()) {
DataRow row = bufferedIterator.next();
Temporal temp = getTemporal(row.getCell(column));
/* Checks if all buffered rows are in the specified window. */
if (!overflow && compareTemporal(temp, m_windowEndTemporal) > 0) {
allBufferedRowsInWindow = false;
break;
}
container.addRowToTable(row);
m_currRow++;
if (overflow || m_lastWindow || compareTemporal(getTemporal(row.getCell(column)), m_nextStartTemporal) < 0) {
bufferedIterator.remove();
}
}
boolean lastEntryMissing = false;
boolean addedNewToBuffer = false;
/* Add newly read rows. */
while (m_rowIterator.hasNext() && allBufferedRowsInWindow) {
DataRow row = m_rowIterator.next();
if (row.getCell(column).isMissing()) {
printMissingWarning();
lastEntryMissing = true;
continue;
}
lastEntryMissing = false;
Temporal currTemporal = getTemporal(row.getCell(column));
/* Check if table is sorted in non-descending order according to temporal column. */
if (compareTemporal(currTemporal, m_prevTemporal) < 0) {
throw new IllegalStateException(m_orderException);
}
m_prevTemporal = currTemporal;
/* Add rows for next window into the buffer. */
if (!m_lastWindow && compareTemporal(currTemporal, m_nextStartTemporal) >= 0 && !overflow) {
m_bufferedRows.add(row);
addedNewToBuffer = true;
}
/* Add row to current output. */
if (overflow || compareTemporal(currTemporal, m_windowEndTemporal) <= 0) {
container.addRowToTable(row);
/* The last entry has been in the current window, thus it is the last one. */
if (!m_rowIterator.hasNext()) {
m_lastWindow = true;
}
m_currRow++;
} else {
break;
}
}
/* Checks if the last row we saw had a missing value. If this is the case the current window is the last window. */
if (lastEntryMissing) {
m_lastWindow = true;
}
/* Find next entry that lies in a following window. */
DataRow row = null;
/* Close iterator if last window has been filled. */
if (m_lastWindow) {
m_rowIterator.close();
} else if (!allBufferedRowsInWindow) {
/* Not all previously buffered rows are in the current window. */
row = m_bufferedRows.remove();
} else if (!m_rowIterator.hasNext() && !addedNewToBuffer) {
/* We already returned the last row, but it would be in the next window. Nevertheless, terminate. */
m_rowIterator.close();
m_lastWindow = true;
} else if (m_bufferedRows.size() == 0) {
/* Buffer is empty, so get next row. */
row = m_rowIterator.next();
while (row.getCell(column).isMissing() && m_rowIterator.hasNext()) {
row = m_rowIterator.next();
printMissingWarning();
}
if (row.getCell(column).isMissing()) {
row = null;
printMissingWarning();
}
} else if (!overflow && !m_bufferedRows.isEmpty()) {
/* Checks if the next buffered row lies within the given window */
if (compareTemporal(m_windowEndTemporal.plus(startInterval), m_windowEndTemporal) > 0) {
Temporal temp = getTemporal(m_bufferedRows.getFirst().getCell(column));
if (compareTemporal(temp, m_windowEndTemporal.plus(startInterval)) >= 0) {
row = m_bufferedRows.removeFirst();
}
}
}
skipTemporalWindow(row, column, startInterval, windowDuration);
container.close();
return new BufferedDataTable[] { container.getTable() };
}
Aggregations