从现在开始获取“几小时前”的日期

我想知道从现在开始的确切日期。我有一个如下所示的输入数据框。年龄列是日期的差异。

我想获得显示的输出数据帧。它是按日期 = 当前日期 - 差值(AGE 数据)计算得出的日期。

有什么办法吗?

输入:

#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>

// Abstratcion of one line with values
struct LineData {
    // Data
    double d{};
    int i{};

    // Extraction operator. Read data with standard approach
    friend std::istream& operator >> (std::istream& is,LineData& d) {
        char c{};
        return is >> d.d >> c >> d.i;
    }
    // Simple insertion operator
    friend std::ostream& operator << (std::ostream& os,const LineData& d) {
        return os << d.d << '\t' << d.i << '\n';
    }
};

// Abstraction of one record. So,many lines with data,with a last line of stars as separator
struct Record {
    // Our data. All lines with the double and integer values
    std::vector<LineData> lineData{};

    // Extractor: Read all values and the last line with starts. Ignore blank lines.
    friend std::istream& operator >> (std::istream& is,Record& r) {

        // Read data,until we hit the end of e record,denoted by stars
        for (bool readingRecord{ true }; readingRecord and is;) {

            // Read a complete line from the stream
            if (std::string line{}; std::getline(is,line))

                // Ignore empty kines
                if (not line.empty())

                    // In case of stars,stop reding line data for this record
                    if (line[0] == '*') readingRecord = false;
                    else {
                        // Put the already read line into a std::istringstream for further extraction
                        std::istringstream iss{ line };
                        LineData ld{};
                        // Call extractor from LineData and add this line data to the record,inc ase of success
                        if (iss >> ld) r.lineData.emplace_back(std::move(ld));
                    }
        }
        return is;
    }
    // Simple inserter
    friend std::ostream& operator << (std::ostream & os,const Record & r) {
        std::copy(r.lineData.begin(),r.lineData.end(),std::ostream_iterator<LineData>(os));
        return os << '\n';
    }
};
// Abstratcion of Data,of the complete file
struct Data {

    // Afile consists of records
    std::vector<Record> data{};

    // Simple extractor operator
    friend std::istream& operator >> (std::istream& is,Data& d) {

        // Read records until end of file
        for (Record r{}; is >> r; d.data.emplace_back(std::move(r)))
            ;
        return is;
    }
    // Simple inserter
    friend std::ostream& operator << (std::ostream& os,const Data& d) {
        std::copy(d.data.begin(),d.data.end(),std::ostream_iterator<Record>(os));
        return os << '\n';
    }
};

int main() {

    // Her all data from the file will be stored
    Data data{};

    // Open file and and check,if it is open
    if (std::ifstream ifs{ "test.txt" }; ifs) {

        // Read complete file and parse it
        ifs >> data;

        // Show result
        std::cout << data;
    }
    return 0;
}

输出:

          AGE
0 '1 years 2 days ago'
1 '3 hours 4 mins ago'
2 '5 mins 6 secs ago'
     ...
HELLO_JAVA521 回答:从现在开始获取“几小时前”的日期

由于您的字符串非常简单,您可以使用 dateparser 而不是实现您自己的解析器。它会自动将您的字符串转换为日期时间对象。

然后您可以使用 strftime 以您选择的格式打印日期时间对象。

例如:

import dateparser
timestrings = ['1 years 2 days ago','3 hours 4 mins ago','5 mins 6 secs ago']

for timestring in timestrings:
    dt = dateparser.parse(timestring)
    print(dt.strftime("%Y-%m-%d %H:%M"))

输出:

2020-07-29 22:33
2021-07-31 19:29
2021-07-31 22:28
,

我能想到的最简单的方法是使用时间增量(如 here 所述)从当前时间中减去您的时间。

这是一个简单的例子:

from datetime import timedelta,datetime
t1 = timedelta(days = 1,hours=7,minutes=36,seconds=20)
print(datetime.now()-t1)

不幸的是,由于闰年之类的原因,当您添加年份时,事情会变得更加复杂。

This computerphile video by Tom Scott 详细解释了您在使用时间时可能遇到的问题。

This 堆栈溢出问题解释了如何仍然可以实现这一点。

,

EDIT:包含月份的另一个版本:

import re
import pandas as pd

units = ("sec","min","hour","day","week","month","year")
re_offset = re.compile("|".join(r"\d+\s*" + f"{unit}s?" for unit in units))
re_num_unit = re.compile(r"(\d+)\s*(\w+)")

def offset(s):
    keys = {
        "sec": "seconds","secs": "seconds","min": "minutes","mins": "minutes","hour": "hours","day": "days","week": "weeks","month": "months","year": "years"
    }

    values = {}
    for num_unit in re_offset.findall(s):
        num_str,unit = re_num_unit.match(num_unit).groups()
        unit = keys.get(unit,unit)
        values[unit] = int(num_str)

    return pd.DateOffset(**values)

df["DATE"] = (dt.datetime.now() - df.AGE.apply(offset)).dt.strftime("%Y-%m-%d %H:%M")

或更短,以防字符串表现得很好:

def offset(lst):
    keys = {
        "sec": "seconds","year": "years"
    }
    return pd.DateOffset(
        **{keys.get(unit,unit): int(num_str) for num_str,unit in lst}
    )

df["DATE"] = (dt.datetime.now()
              - df.AGE.str.findall(r"(\d+)\s*(\w+)")
                      .map(offset)).dt.strftime("%Y-%m-%d %H:%M")

旧版本:

import re
import datetime as dt

units = ("sec","year")
re_timedelta = re.compile("|".join(r"\d+\s*" + f"{unit}s?" for unit in units))
re_num_unit = re.compile(r"(\d+)\s*(\w+)")

def ago(s,now):
    keys = {
        "sec": "seconds","year": "years"
    }
    values = {"seconds": 0,"minutes": 0,"hours": 0,"days": 0,"weeks": 0}
    
    for num_unit in re_timedelta.findall(s):
        num_str,unit)
        if unit == "years":
            years = int(num_str)
            if now.month == 2 and now.day == 29 and years%4:
                ago_date = dt.date(now.year - years,3,1)
            else:
                ago_date = dt.date(now.year - years,now.month,now.day)
            values["days"] += (now.date() - ago_date).days
        else:
            values[unit] += int(num_str)
    
    return (now - dt.timedelta(**values)).strftime("%Y-%m-%d %H:%M")

有了这些准备,您就可以做到(df 您的数据框):

now = dt.datetime.now()
df["DATE"] = df.AGE.apply(ago,args=[now])

结果:

                  AGE              DATE
0  1 years 2 days ago  2020-07-29 17:51
1  3 hours 4 mins ago  2021-07-31 14:47
2   5 mins 6 secs ago  2021-07-31 17:46
,

可以做类似的事情,我们可以使用 date 模块来获取确切的日期和时间并将其与输入进行比较。代码如下:

from datetime import datetime

#Get the current year (I will make a simpler version,only with the year,it will be the same idea for days,months,etc.)
currentYear = datetime.now().strftime("%Y")

#Input the year to be substracted
secondYear = int(input("What is the year to be substracted?"))

#We will use the int() function on the currentYear variable because normally it is a string type var
#Substract the two years
print(int(currentYear) - secondYear)

我希望你能理解我的意思,我用了一个更简单的例子来向你展示它是如何完成的。您可以在其他日期使用相同的技术。

本文链接:https://www.f2er.com/5515.html

大家都在问