Back to column formats
Column formattingSharePoint Online

Page-a-day Calendar

This sample customizes a date column to look like a page-a-day calendar. It does this by using the date part functions (`getDate`, `getMonth`, and `getYear`).

Page-a-day Calendar formatting preview
Sample preview · View original image

Copy. Apply. Make it yours.

Get this format

6 definitions

Review the requirements below, then paste this JSON into the matching formatting panel. Show me where.

Use your list's internal column names and replace any tenant-specific URLs or flow IDs. Formatting is presentation, not a way to secure data.

Column formatting
Download JSON
{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
  "elmType": "div",
  "style": {
    "display": "=if(@currentField,'flex','none')",
    "margin": "5px 0",
    "justify-content": "center"
  },
  "children": [
    {
      "elmType": "div",
      "attributes": {
        "class": "ms-bgColor-themePrimary"
      },
      "style": {
        "display": "flex",
        "flex-direction": "column",
        "width": "54px",
        "border-radius": "8px",
        "box-shadow": "0 1px 3px rgba(0,0,0,0.1), 0 4px 6px rgba(0,0,0,0.1)",
        "background-color": "=if(toDateString(@currentField)==toDateString(@now),'#c43b33','')"
      },
      "children": [
        {
          "elmType": "div",
          "txtContent": "=substring('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC',getMonth(@currentField)*3,getMonth(@currentField)*3+3)",
          "style": {
            "display": "flex",
            "justify-content": "center",
            "letter-spacing": "1px",
            "padding": "2px 0 2px 0",
            "color": "white",
            "font-weight": "bold"
          }
        },
        {
          "elmType": "div",
          "style": {
            "display": "flex",
            "background-color": "white",
            "border-radius": "0 0 7px 7px",
            "flex-direction": "column",
            "padding": "0px 2px 3px 2px",
            "line-height": "1.2"
          },
          "children": [
            {
              "elmType": "div",
              "style": {
                "display": "flex",
                "flex-direction": "row",
                "align-items": "flex-start",
                "justify-content": "space-between"
              },
              "children": [
                {
                  "elmType": "div",
                  "style": {
                    "display": "=if(Date(toDateString(@currentField))<Date(toDateString(@now)),'flex','none')",
                    "flex-direction": "column",
                    "align-items": "center",
                    "justify-content": "flex-start",
                    "color": "red",
                    "font-size": "10px"
                  },
                  "children": [
                    {
                      "elmType": "div",
                      "txtContent": "=if(floor((@now-Date(toDateString(@currentField)))/86400000)>30,'30+',floor((@now-Date(toDateString(@currentField)))/86400000))"
                    },
                    {
                      "elmType": "div",
                      "txtContent": "←",
                      "style": {
                        "line-height": "0.5"
                      }
                    }
                  ]
                },
                {
                  "elmType": "div",
                  "style": {
                    "display": "flex",
                    "flex-direction": "column",
                    "flex-grow": "1"
                  },
                  "children": [
                    {
                      "elmType": "div",
                      "txtContent": "=getDate(@currentField)",
                      "style": {
                        "display": "flex",
                        "justify-content": "center",
                        "font-size": "22px",
                        "font-weight": "bold"
                      }
                    }
                  ]
                },
                {
                  "elmType": "div",
                  "style": {
                    "display": "=if(Date(toDateString(@currentField))>@now,'flex','none')",
                    "flex-direction": "column",
                    "align-items": "center",
                    "color": "green",
                    "font-size": "10px",
                    "justify-content": "flex-start"
                  },
                  "children": [
                    {
                      "elmType": "div",
                      "txtContent": "=if(ceiling((Date(toDateString(@currentField))-@now)/86400000)>30,'30+',ceiling((Date(toDateString(@currentField))-@now)/86400000))"
                    },
                    {
                      "elmType": "div",
                      "txtContent": "→",
                      "style": {
                        "line-height": "0.5"
                      }
                    }
                  ]
                }
              ]
            },
            {
              "elmType": "div",
              "style": {
                "display": "flex",
                "justify-content": "center",
                "padding-bottom": "2px"
              },
              "children": [
                {
                  "elmType": "span",
                  "txtContent": "=substring('SUNMONTUEWEDTHUFRISAT',((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0)+floor((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0))/4)-floor((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0))/100)+floor((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0))/400)+1*substring('032503514624',getMonth(@currentField),getMonth(@currentField)+1)+getDate(@currentField))%7)*3,((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0)+floor((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0))/4)-floor((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0))/100)+floor((getYear(@currentField)-if((getMonth(@currentField)+1)<3,1,0))/400)+1*substring('032503514624',getMonth(@currentField),getMonth(@currentField)+1)+getDate(@currentField))%7)*3+3)",
                  "style": {
                    "background-color": "#4c4c4c",
                    "color": "white",
                    "font-size": "10px",
                    "border-radius": "3px",
                    "padding": "0px 4px 1px 4px"
                  }
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

From the contributor

How to use this sample

Summary

This sample customizes a date column to look like a page-a-day calendar. It does this by using the date part functions (getDate, getMonth, and getYear). The days of the week are displayed using Zeller's congruence and Tomohiko Sakamoto's method.

screenshot of the sample

View requirements

This format can be applied to a Date column.

Sample

Solution Author(s)
date-page-a-day-calendar.json Tetsuya Kawahara
date-page-a-day-calendar-minimal.json Watana
date-page-a-day-calendar-prev-today-next.json Watana
date-page-a-day-calendar-weekend.json Watana
date-page-a-day-calendar-30d-counter.json Watana
date-page-a-day-calendar-30d-counter-dow.json Watana

Version history

Version Date Comments
1.0 October 17, 2020 Initial release
1.1 August 2, 2021 Fixed to show days of the week.
1.2 October 2, 2022 Fixed incorrect days of the week being displayed.
1.3 December 13, 2024 Added date-page-a-day-calendar-minimal.json
1.4 December 14, 2024 Adjusted the layout for date-page-a-day-calendar.json to ensure that the day-of-the-week text, which was partially hidden due to the update, is now visible.
1.5 September 1, 2025 Added date-page-a-day-calendar-prev-today-next.json
1.6 September 13, 2025 Added date-page-a-day-calendar-weekend.json
1.7 October 1, 2025 Added date-page-a-day-calendar-30d-counter.json & date-page-a-day-calendar-30d-counter-dow.json and refactored previous samples.

Disclaimer

THIS CODE IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

Additional notes