# Day of the Year
**Difficulty:** EASY
[External](https://leetcode.com/problems/day-of-the-year)
Canonical: https://scaleengineer.com/dsa/problems/day-of-the-year
**Patterns:** [Math](https://scaleengineer.com/dsa/patterns/math)
**Data structures:** String
**Companies:** [ZScaler](https://scaleengineer.com/companies/zscaler)
---
## Problem
Given a string `date` representing a [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian%5Fcalendar) date formatted as `YYYY-MM-DD`, return _the day number of the year_.

**Example 1:**

**Input:** date = "2019-01-09"
**Output:** 9
**Explanation:** Given date is the 9th day of the year in 2019.

**Example 2:**

**Input:** date = "2019-02-10"
**Output:** 41

**Constraints:**

* `date.length == 10`
* `date[4] == date[7] == '-'`, and all other `date[i]`'s are digits
* `date` represents a calendar date between Jan 1st, 1900 and Dec 31st, 2019.

# Approaches
## Using Built-in Date/Time Libraries
This approach leverages the language's standard date and time libraries to simplify the problem. We parse the input string into a date object and then use a built-in method to directly retrieve the day of the year.
**Time:** O(1). While there is some overhead in parsing and object creation, for a fixed-format input string, the time taken is constant and does not scale with any input size. · **Space:** O(1). A single `LocalDate` object of a fixed size is created.
**Pros:** Extremely concise and readable code.; Highly reliable as it relies on well-tested standard library functions, eliminating risks of manual calculation errors (e.g., leap year logic).
**Cons:** May introduce a slight performance overhead compared to a direct manual calculation, due to the creation of date objects.; Might not be permissible in interview settings that aim to test fundamental algorithm implementation skills.
### Explanation
Modern programming languages like Java provide powerful libraries for handling dates and times. In Java 8 and later, the `java.time` package is the standard.

We can use `java.time.LocalDate.parse(date)` to convert the input string `YYYY-MM-DD` directly into a `LocalDate` object. The format matches the ISO-8601 standard, which is the default for `LocalDate.parse`.

Once we have the `LocalDate` object, we can simply call the `getDayOfYear()` method on it. This method handles all the complexities of calendar calculations, including leap years, internally.

```java
import java.time.LocalDate;

class Solution {
    public int dayOfYear(String date) {
        // The input string "YYYY-MM-DD" is in ISO-8601 format,
        // which is the default format for LocalDate.parse().
        LocalDate localDate = LocalDate.parse(date);
        
        // getDayOfYear() returns the day of the year, from 1 to 365 or 366.
        return localDate.getDayOfYear();
    }
}
```
### Algorithm
- Use the built-in date parsing function (e.g., `LocalDate.parse()` in Java) to convert the input string into a date object.
- Call the corresponding method (e.g., `getDayOfYear()`) on the date object to get the day number of the year.
- Return the result.

## Manual Calculation with Precomputed Days
This approach involves manually parsing the year, month, and day from the input string. We then calculate the day of the year by summing the days of the preceding months and adding the day of the current month, accounting for leap years.
**Time:** O(1), as the number of months to iterate through is constant (at most 12). String parsing on a fixed-length string is also a constant time operation. · **Space:** O(1), as we only use a fixed-size array to store the number of days in each month.
**Pros:** Efficient and self-contained, with no external library dependencies.; Demonstrates a clear understanding of calendar arithmetic and leap year rules.
**Cons:** Requires careful implementation to avoid off-by-one errors or incorrect leap year logic.; More verbose than using a built-in library.
### Explanation
We first extract the year, month, and day from the `YYYY-MM-DD` formatted string. This can be done using `substring` and `Integer.parseInt`.

We use a precomputed array to store the number of days in each month of a common year: `{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}`.

We initialize a variable, say `dayCount`, to 0. We then loop from the first month up to the month before the given month, adding the number of days from our precomputed array to `dayCount`. After the loop, we add the day of the given month to `dayCount`.

Finally, we need to handle the leap year case. A year is a leap year if it is divisible by 400, or if it is divisible by 4 but not by 100. If the given year is a leap year, we simply update the number of days for February to 29 before starting our summation. The final `dayCount` is the day number of the year.

```java
class Solution {
    public int dayOfYear(String date) {
        int year = Integer.parseInt(date.substring(0, 4));
        int month = Integer.parseInt(date.substring(5, 7));
        int day = Integer.parseInt(date.substring(8, 10));

        int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        
        // Check for leap year and update February's days
        if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) {
            daysInMonth[1] = 29;
        }

        int dayOfYear = 0;
        for (int i = 0; i < month - 1; i++) {
            dayOfYear += daysInMonth[i];
        }
        
        dayOfYear += day;
        
        return dayOfYear;
    }
}
```
### Algorithm
- Parse `year`, `month`, and `day` from the input string.
- Define an array `daysInMonth` for a common year.
- Check if `year` is a leap year. If it is, update the number of days for February in the array to 29.
- Initialize `totalDays` to 0.
- Iterate from month 1 to `month - 1`. In each iteration, add the number of days of the current month from the `daysInMonth` array to `totalDays`.
- Add the `day` to `totalDays`.
- Return `totalDays`.

# Solutions
### Java

```java
class Solution {
public
  int dayOfYear(String date) {
    int y = Integer.parseInt(date.substring(0, 4));
    int m = Integer.parseInt(date.substring(5, 7));
    int d = Integer.parseInt(date.substring(8));
    int v = y % 400 == 0 || (y % 4 == 0 && y % 100 != 0) ? 29 : 28;
    int[] days = {31, v, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int ans = d;
    for (int i = 0; i < m - 1; ++i) {
      ans += days[i];
    }
    return ans;
  }
}

```

### JavaScript

```javascript
/** * @param {string} date * @return {number} */ var dayOfYear = function (
  date,
) {
  const y = +date.slice(0, 4);
  const m = +date.slice(5, 7);
  const d = +date.slice(8);
  const v = y % 400 == 0 || (y % 4 == 0 && y % 100) ? 29 : 28;
  const days = [31, v, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  return days.slice(0, m - 1).reduce((a, b) => a + b, d);
};

```

### CPP

```cpp
class Solution {
public:
  int dayOfYear(string date) {
    int y, m, d;
    sscanf(date.c_str(), "%d-%d-%d", &y, &m, &d);
    int v = y % 400 == 0 || (y % 4 == 0 && y % 100) ? 29 : 28;
    int days[] = {31, v, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int ans = d;
    for (int i = 0; i < m - 1; ++i) {
      ans += days[i];
    }
    return ans;
  }
};

```

### Python

```python
class Solution:
    def dayOfYear(self, date: str) -> int: y, m, d = (int(s) for s in date . split('-')) v = 29 if y % 400 == 0 or (y % 4 == 0 and y % 100) else 28 days = [31, v, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] return sum(days[: m - 1]) + d

```
