F # Как сравнить два значения DateTime - PullRequest
0 голосов
/ 06 ноября 2018

Я исследовал этот вопрос, но ответы, которые я нахожу, для C #, а не F #. Похоже, мне нужно использовать DateTime.Compare, но я надеялся на собственное решение.

Цель функции (ниже) - определить, является ли время доступа одного файла> = к пороговому значению. Пороговое значение является последним временем доступа с числом дней, вычтенных из последнего времени доступа.

days_old передается в функцию isFileStale вместе с именем файла fn.

Я просто озадачен, почему эта функция всегда возвращает false.

let isFileStale fn days_old  =
    let rc =
        let currentTime = ((System.DateTime.Now).ToLocalTime())
        let lastFileUsed = File.GetLastAccessTime(fn)
        let timeSpan = new TimeSpan(days_old, 0, 0, 0, 0)
        let fileDeleteThreshhold = lastFileUsed.Subtract(timeSpan)

        if fileDeleteThreshhold >= lastFileUsed then
            true
        else
            false
    rc

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Кстати, как общее практическое правило, всякий раз, когда вы используете DateTime.Now внутри функции, я бы рекомендовал превратить ее в функцию pure , переместив currentTime в параметр. Это делает ваше модульное тестирование намного проще, потому что вам не нужно высмеивать DateTime.Now, вам просто нужно пройти время, которое вы хотите, чтобы быть «текущим» временем для этого модульного теста. Например, чтобы проверить isFileStale с вашей текущей функцией, ваш модульный тест должен будет проверить текущее время, создать файл с отметкой времени (текущее время - N дней), а затем вызвать isFileStale для этого файла. Но с версией isFileStale, которая принимает currentTime в качестве параметра, ваш тест будет:

  • Создание файла с отметкой времени 2010-01-01
  • Это 7 дней 2010-01-07? Ответ должен быть "нет".
  • Это 7 дней 2010-01-08? Ответ должен быть "да".

Это также позволяет вам легко тестировать такие вещи, как 29 февраля, без необходимости запускать ваши модульные тесты точно в нужное время каждые четыре года.

Теперь для такой простой функции, как isFileStale, это может не понадобиться. Но это хорошее правило, чтобы запомнить. Я бы порекомендовал написать следующую пару функций (начиная с кода gileCAD, так как он отлично):

let isFileStale currentTime days_old fn  =
    let lastFileUsed = File.GetLastAccessTime(fn)
    (currentTime - lastFileUsed).Days >= days_old

let isFileOlderThanNDays days_old fn =
    isFileStale DateTime.Now days_old fn

Обратите внимание, что я поменял местами параметры days_old и fn, потому что это позволяет вам писать код, который имеет смысл в конвейере:

if "/path/to/file" |> isFileOlderThanNDays 7 then
    printfn "File is at least a week old"
else
    printfn "File is relatively fresh"
0 голосов
/ 07 ноября 2018

Я не уверен, что понимаю, что вы пытаетесь сделать, но вы всегда получаете ложь, потому что lastFileUsed.Subtract(timeSpan) (что является вашим fileDeleteThreshhold значением) всегда будет ниже lastFileUsed (или равно, когда days_old = 0)

Может быть, это то, что вы ищете:

let isFileStale fn days_old  =
    let currentTime = DateTime.Now
    let lastFileUsed = File.GetLastAccessTime(fn)
    (currentTime - lastFileUsed).Days >= days_old
...