Search code examples
ansiblejinja2

From a list, how to get only the items with dates within a certain time period?


I have a list of items, each item has a date value:

[
  {
    "Date Merged": "6/1/2023 3:46:53 PM",
    "PR ID": "470"
  },
  {
    "Date Merged": "5/30/2023 2:44:25 PM",
    "PR ID": "447"
  }
]

I want to get only the PRs of the items with dates that happened in May. I think I can grab the 'PR ID' values with: map(attribute='PR ID'), but I don't know how to filter within a certain date range.


Solution

  • Given the data

      prs:
        - Date Merged: 6/1/2023 3:46:53 PM
          PR ID: '470'
        - Date Merged: 5/30/2023 2:44:25 PM
          PR ID: '447'
    

    Q: "Get the PRs with dates that happened in May."

    A: There are more options:

    • Quick & dirty. The test match "succeeds if it finds the pattern at the beginning of the string"
      result: "{{ prs|selectattr('Date Merged', 'match', '5')|
                      map(attribute='PR ID') }}"
    

    gives

      result:
      - '447'
    
    • Use the filter to_datetime to get the date objects and create the list of the hashes
      format: '%m/%d/%Y %I:%M:%S %p'
      months: "{{ prs|map(attribute='Date Merged')|
                      map('to_datetime', format)|
                      map(attribute='month')|
                      map('community.general.dict_kv', 'month') }}"
    

    gives

      months:
      - month: 6
      - month: 5
    

    Update the dictionaries

      prs_months: "{{ prs|zip(months)|map('combine') }}"
    

    gives

      prs_months:
      - Date Merged: 6/1/2023 3:46:53 PM
        PR ID: '470'
        month: 6
      - Date Merged: 5/30/2023 2:44:25 PM
        PR ID: '447'
        month: 5
    

    Select the items and get the ids

      result: "{{ prs_months|selectattr('month', 'eq', 5)|
                             map(attribute='PR ID') }}"
    

    gives the same result

      result:
      - '447'
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        prs:
          - Date Merged: 6/1/2023 3:46:53 PM
            PR ID: '470'
          - Date Merged: 5/30/2023 2:44:25 PM
            PR ID: '447'
    
        result1: "{{ prs|selectattr('Date Merged', 'match', '5')|
                         map(attribute='PR ID') }}"
    
        format: '%m/%d/%Y %I:%M:%S %p'
        months: "{{ prs|map(attribute='Date Merged')|
                        map('to_datetime', format)|
                        map(attribute='month')|
                        map('community.general.dict_kv', 'month') }}"
        prs_months: "{{ prs|zip(months)|map('combine') }}"
        result2: "{{ prs_months|selectattr('month', 'eq', 5)|
                                map(attribute='PR ID') }}"
    
      tasks:
    
        - debug:
            var: result1
    
        - debug:
            var: months
        - debug:
            var: prs_months
        - debug:
            var: result2