© 2024 IQVIA - All Rights Reserved

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Summary

This edit check interrogates Incomplete DateTime and Partial DateTime items to ensure that the entered timing components are logical.

Logic

This edit check will elicit an alert if a ‘lower level’ timing component is specified without the the full hierarchy of ‘higher level’ components also specified. For example:

  • Seconds are specified; but not Minutes, Hours, Day, Month, and Year

  • Minutes are specified; but not Hours, Day, Month, and Year

  • Hours are specified; but not Day, Month, and Year

  • Day is specified; but not Month and Year

  • Month is specified; but not Year

Formal Expression

function getTimeZoneOffset(timeZoneId) {
    var timezoneOffsets = {
        "US/Pacific": -7 * 60 * 60 * 1000,
        "US/Mountain": -6 * 60 * 60 * 1000,
        "US/Central": -5 * 60 * 60 * 1000,
        "US/Eastern": -4 * 60 * 60 * 1000,
        "Europe/London": 0 * 60 * 60 * 1000,
        "Europe/Berlin": 1 * 60 * 60 * 1000,
        "Europe/Paris": 1 * 60 * 60 * 1000,
        "Europe/Madrid": 1 * 60 * 60 * 1000,
        "Europe/Rome": 1 * 60 * 60 * 1000,
        "Europe/Warsaw": 1 * 60 * 60 * 1000,
        "Europe/Moscow": 3 * 60 * 60 * 1000,
        "UTC": 0 * 60 * 60 * 1000,
        "GMT": 0 * 60 * 60 * 1000,
    };

    return timezoneOffsets[timeZoneId] || 0;
}

function normalizeIncompleteDatetime(value, timeZoneId) {
    logger("Original value: " + value);

    // Split the date and time parts
    var parts = value.split('T');
    var datePart = parts[0].split('-');

    // Default year, month, and day
    var year = datePart[0] ? parseInt(datePart[0], 10) : 0;
    var month = datePart[1] && datePart[1].trim() !== '' ? parseInt(datePart[1], 10) - 1 : 0;  // Default to January (month = 0)
    var day = datePart[2] && datePart[2].trim() !== '' ? parseInt(datePart[2], 10) : 1;        // Default to 1st of the month

    // Split the time part and pad missing parts with defaults
    var timePart = parts.length > 1 ? parts[1].split(':') : [];
    var hour = timePart[0] && timePart[0].trim() !== '' ? parseInt(timePart[0], 10) : 0;
    var minute = timePart[1] && timePart[1].trim() !== '' ? parseInt(timePart[1], 10) : 0;
    var second = timePart.length > 2 && timePart[2].trim() !== '' ? parseInt(timePart[2], 10) : 0;

    // Create the Date object directly in the local timezone
    var normalizedDatetime = new Date(year, month, day, hour, minute, second);

    // Check if the date is valid
    if (isNaN(normalizedDatetime.getTime())) {
        logger("Error: Invalid Date created from input value.");
        customErrorMessage('The datetime "' + value + '" could not be interpreted as a valid date.');
        return null;
    }

    // Adjust the datetime according to the timezone offset
    var timezoneOffset = getTimeZoneOffset(timeZoneId);
    normalizedDatetime = new Date(normalizedDatetime.getTime() - timezoneOffset);  // Corrected: Subtracting the offset to convert from MT to UTC
    logger("Date object adjusted for " + timeZoneId + ": " + normalizedDatetime);

    return normalizedDatetime;
}

function isNotInFuture(datetimeValue, timeZoneId) {
    logger("Starting isNotInFuture check...");

    // Normalize the incomplete datetime value directly in the timezone
    var normalizedDatetime = normalizeIncompleteDatetime(datetimeValue, timeZoneId);
    if (!normalizedDatetime) {
        // Return false if we couldn't create a valid date
        return false;
    }

    logger("Normalized datetime for comparison: " + normalizedDatetime);

    // Get the current time adjusted to the local timezone
    var now = new Date();
    logger("Current local time: " + now);

    // Compare the datetime
    if (normalizedDatetime.getTime() >= now.getTime()) {
        var errorMessage = 'The datetime "' + datetimeValue + '" is in the future or exactly at the current time, which is not allowed.';
        logger("Error: " + errorMessage);
        customErrorMessage(errorMessage);
        return false;
    }

    logger("Datetime is not in the future.");
    return true;
}

// Extract the timezone from formJson
var timeZoneId = formJson.form.subject.volunteer.site.timeZoneId;
logger("TimeZone ID: " + timeZoneId);

// Run the check against the provided item value
logger("Item value: " + itemJson.item.value);
var isValid = isNotInFuture(itemJson.item.value, timeZoneId);
logger("Validation result: " + isValid);
return isValid;

  • No labels