How do I get number of each day for a certain month in Java?

You can get the number of each day (Monday, Tuesday, etc.) for a specific month in Java using the java.time package introduced in Java 8. In the following code snippet we will use a loop to iterate the dates in the month. The number of loop is equals to the number of days in the month.

You can run this code to get the count of each day of the week for any specific month and year. Here’s a sample code to achieve that:

package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.EnumMap;
import java.util.Map;

public class DaysOfWeekInMonthWithLoop {

    public static Map<DayOfWeek, Integer> getDaysCountForMonth(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate firstOfMonth = yearMonth.atDay(1);
        LocalDate lastOfMonth = yearMonth.atEndOfMonth();

        Map<DayOfWeek, Integer> daysCount = new EnumMap<>(DayOfWeek.class);

        for (DayOfWeek day : DayOfWeek.values()) {
            daysCount.put(day, 0);
        }

        for (LocalDate date = firstOfMonth; !date.isAfter(lastOfMonth); date = date.plusDays(1)) {
            DayOfWeek dayOfWeek = date.getDayOfWeek();
            daysCount.put(dayOfWeek, daysCount.get(dayOfWeek) + 1);
        }

        return daysCount;
    }

    public static void main(String[] args) {
        int year = 2024;
        int month = 10; // October

        Map<DayOfWeek, Integer> daysCount = getDaysCountForMonth(year, month);

        for (Map.Entry<DayOfWeek, Integer> entry : daysCount.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

Output:

MONDAY: 4
TUESDAY: 5
WEDNESDAY: 5
THURSDAY: 5
FRIDAY: 4
SATURDAY: 4
SUNDAY: 4

What we do in the code snippet above:

  1. YearMonth: Used to represent the year and month. You create an instance of YearMonth for the desired year and month.
  2. LocalDate: Represents a date (year, month, day). firstOfMonth is the first day of the month and lastOfMonth is the last day of the month.
  3. EnumMap: A specialized map for use with enum keys, which in this case are days of the week (from DayOfWeek enum).
  4. Loop through Dates: Iterate from the first to the last day of the month. For each date, get the day of the week and update the count in the map.

Another solution that we can use is to calculate the number of days using a simple mathematical calculations instead of iterating through the dates of the month.

The refined approach:

  1. Determine the first day of the month.
  2. Calculate the base number of times each day appears:
    • Each day will appear at least daysInMonth / 7 times because every 7-day week will have each day once.
    • The remainder from daysInMonth % 7 will determine how many days are left over from complete weeks, starting from the first day of the month.

Here is how we can implement it:

package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.EnumMap;
import java.util.Map;

public class DaysOfWeekInMonth {

    public static Map<DayOfWeek, Integer> getDaysCountForMonth(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate firstDayOfMonth = yearMonth.atDay(1);

        int daysInMonth = yearMonth.lengthOfMonth();
        DayOfWeek firstDayOfWeek = firstDayOfMonth.getDayOfWeek();

        Map<DayOfWeek, Integer> daysCount = new EnumMap<>(DayOfWeek.class);

        int baseCount = daysInMonth / 7;
        int extraDays = daysInMonth % 7;

        for (DayOfWeek day : DayOfWeek.values()) {
            daysCount.put(day, baseCount);
        }

        for (int i = 0; i < extraDays; i++) {
            DayOfWeek currentDay = firstDayOfWeek.plus(i);
            daysCount.put(currentDay, daysCount.get(currentDay) + 1);
        }

        return daysCount;
    }

    public static void main(String[] args) {
        int year = 2024;
        int month = 10; // October

        Map<DayOfWeek, Integer> daysCount = getDaysCountForMonth(year, month);

        for (Map.Entry<DayOfWeek, Integer> entry : daysCount.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

Output:

MONDAY: 4
TUESDAY: 5
WEDNESDAY: 5
THURSDAY: 5
FRIDAY: 4
SATURDAY: 4
SUNDAY: 4

In this approach:

  1. YearMonth: Represents the year and month.
  2. LocalDate: Determines the first day of the month.
  3. DayOfWeek: Identifies the day of the week for the first day of the month.
  4. EnumMap: Stores the count of each day of the week.
  5. Base Count and Remainder:
    • baseCount: Calculates how many whole weeks (7 days) fit in the month.
    • extraDays: Calculates the remaining days after accounting for whole weeks.
    • Initialize each count in the map to baseCount.
    • Add 1 to the first extraDays days in the week starting from firstDayOfWeek.

This approach avoids explicitly iterating over each day in the month and relies on mathematical operations to determine the count of each day of the week.

How do I get operating system process information using ProcessHandle?

Java 9 introduced the ProcessHandle API, which allows us to interact with and retrieve information about native processes. Here’s how we can use ProcessHandle to get information about operating system processes:

We can list all the processes currently running on the system and print their details:

package org.kodejava.example.lang;

import java.time.Duration;
import java.time.Instant;

public class ProcessHandleExample {
    public static void main(String[] params) {
        ProcessHandle.allProcesses()
                .forEach(process -> {
                    long pid = process.pid();
                    ProcessHandle.Info info = process.info();
                    String cmd = info.command().orElse("");
                    String[] args = info.arguments().orElse(new String[0]);
                    Instant startTime = info.startInstant().orElse(null);
                    Duration cpuUsage = info.totalCpuDuration().orElse(Duration.ZERO);

                    System.out.println("PID        = " + pid);
                    System.out.println("Command    = " + cmd);
                    System.out.println("Args       = " + String.join(" ", args));
                    System.out.println("Start Time = " + startTime);
                    System.out.println("CPU Usage  = " + cpuUsage);
                    System.out.println("------------");
                });
    }
}

If we want to get information about a specific process, we can use their process ID (PID):

package org.kodejava.example.lang;

import java.time.Duration;
import java.time.Instant;
import java.util.Optional;

public class SpecificProcessInfo {
    public static void main(String[] params) {
        // Replace with the PID of the process you want to query
        long pid = 33656;

        // Get the ProcessHandle of the specific process
        Optional<ProcessHandle> processHandle = ProcessHandle.of(pid);
        if (processHandle.isPresent()) {
            ProcessHandle process = processHandle.get();
            pid = process.pid();
            ProcessHandle.Info info = process.info();
            String cmd = info.command().orElse("");
            String[] args = info.arguments().orElse(new String[0]);
            Instant startTime = info.startInstant().orElse(null);
            Duration cpuUsage = info.totalCpuDuration().orElse(Duration.ZERO);

            System.out.println("PID        = " + pid);
            System.out.println("Command    = " + cmd);
            System.out.println("Args       = " + String.join(" ", args));
            System.out.println("Start Time = " + startTime);
            System.out.println("CPU Usage  = " + cpuUsage);
            System.out.println("------------");
        } else {
            System.out.println("No process found with PID: " + pid);
        }
    }
}

Output:

PID        = 33656
Command    = C:\Users\wayan\AppData\Local\Programs\IntelliJ IDEA Ultimate\bin\idea64.exe
Args       = 
Start Time = 2024-07-22T03:14:07.825Z
CPU Usage  = PT46M27.484375S
------------

Explanation

  • ProcessHandle.allProcesses(): returns a stream of all processes currently running on the system.
  • ProcessHandle.of(pid): returns an Optional<ProcessHandle> for the process with the given PID.
  • ProcessHandle.Info: contains information about a process, such as its command, arguments, start time, and CPU usage.
  • info.command(): returns an Optional<String> with the command used to start the process.
  • info.arguments(): returns an Optional<String[]> with the arguments passed to the process.
  • info.startInstant(): returns an Optional<Instant> with the start time of the process.
  • info.totalCpuDuration(): returns an Optional<Duration> with the total CPU time used by the process.

Using the ProcessHandle API in Java 9 and later makes it straightforward to get detailed information about operating system processes.

How do I sum a BigDecimal property of a list of objects using Java Stream API?

If we have a list of objects, and we want to sum a BigDecimal property of these objects, we can achieve this using the Java Stream API. This API provides a clean and efficient way to process collections of objects. To sum the BigDecimal amounts, you can use the map and reduce methods of the Stream API.

As an example, we have a class named Transaction with a BigDecimal property named amount. We have a list of Transaction objects, and we want to calculate the total sum of the amount properties.

In the code snippet below we do the following:

  • Creating Transactions: We create a list of Transaction objects, each with a different BigDecimal amount.
  • Filter Transactions and its amount: We filter to exclude the null transaction and null transaction amount.
  • Mapping to Amounts: We use the map method to convert each Transaction object to its amount property.
  • Summing the Amounts: The reduce method takes two parameters: an identity value (BigDecimal.ZERO) and an accumulator function (BigDecimal::add). The accumulator function adds each BigDecimal in the stream to the running total.
  • Printing the Result: Finally, we print the total sum of the amounts.
package org.kodejava.stream;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

public class BigDecimalSumExample {
    public static void main(String[] args) {
        // Create a list of transaction objects
        List<Transaction> transactions = Arrays.asList(
                new Transaction(new BigDecimal("10.50")),
                null,
                new Transaction(new BigDecimal("30.25")),
                new Transaction(null),
                new Transaction(new BigDecimal("11.49"))
        );

        // Sum the amount properties using stream
        BigDecimal totalAmount = transactions.stream()
                // Filter out null Transaction objects and Transaction objects
                // with null amounts
                .filter(t -> t != null && t.getAmount() != null)
                .map(Transaction::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // Print the result
        System.out.println("Total Amount: " + totalAmount);
    }

    static class Transaction {
        private final BigDecimal amount;

        public Transaction(BigDecimal amount) {
            this.amount = amount;
        }

        public BigDecimal getAmount() {
            return amount;
        }
    }
}

Below is another example, we want to sum just a List<BigDecimal> values. To sum the values we can use the reduce method as shown in the code snippet below.

package org.kodejava.stream;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class BigDecimalListSumExample {
    public static void main(String[] args) {
        // Create a list of BigDecimal values
        List<BigDecimal> amounts = Arrays.asList(
                new BigDecimal("10.50"),
                new BigDecimal("20.75"),
                new BigDecimal("30.25"),
                null,
                new BigDecimal("11.49")
        );

        // Sum the BigDecimal values using stream
        BigDecimal totalAmount = amounts.stream()
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // Print the result
        System.out.println("Total Amount: " + totalAmount);
    }
}

Using Java Stream API to sum a BigDecimal property of a list of objects or a list of BigDecimal values are both concise and efficient. The map and reduce methods streamline the process, making our code more readable and maintainable. This approach can be applied to various scenarios where we need to aggregate data from a list of objects.

How do I convert date string from one format to another format?

In the following code snippet we will see hot to change a date from one format to another format. For example from 2024-11-04 to 04-Nov-24 format in Java. We can use the DateTimeFormatter class from the java.time.format package to do the conversion.

The steps are:

  • Parse the original date string.
  • Format it to the desired pattern.

Here’s the complete code to do this:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateFormatConversion {
    public static void main(String[] args) {
        // The original date string
        String originalDate = "2024-11-04";

        // Define the input and output date formats
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd-MMM-yy");

        // Parse the original date
        LocalDate date = LocalDate.parse(originalDate, inputFormatter);

        // Format the date to the desired pattern
        String formattedDate = date.format(outputFormatter);

        // Print the formatted date
        System.out.println(formattedDate);
    }
}

Output:

04-Nov-24

In the code above we define two formatters, one for the original date format, and the second one is for the new date format. The input formatter matches the original date format (yyyy-MM-dd). The output formatter specifies the desired format (dd-MMM-yy).

We use the LocalDate.parse() method to parse the string of original date into a LocalDate object. Next, we use the LocalDate.format() method to convert into a new date format using the defined formatter object.

This approach uses java.time API introduced in Java 8, which is the recommended way to handle date and time in Java due to its immutability and thread-safety features.

How do I update records in MS Access database?

In this post, we will learn how to update records in a database using the Java Database Connectivity (JDBC) API. JDBC is a Java API which is used to connect and execute query in the database.

We will be working with an MS Access database file named musicdb.accdb for this example. Our goal is to update an album’s title and release date in our album table.

The following code snippet show you how to do it. The selectAlbum() method is just a helper method to show the album data before and after the data was updated.

package org.kodejava.jdbc;

import java.sql.*;
import java.time.LocalDate;
import java.time.Month;

public class MSAccessUpdate {
    public static void main(String[] args) {
        String url = "jdbc:ucanaccess://C:/Users/wayan/Temp/musicdb.accdb";
        try (Connection conn = DriverManager.getConnection(url)) {
            conn.setAutoCommit(false);
            selectAlbum(conn, 2L);

            String sql = """
                    update album
                        set title = ?,
                        release_date = ?
                    where id = ?
                    """;

            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, "A Hard Day's Night");
            ps.setDate(2, Date.valueOf(LocalDate.of(1964, Month.JULY, 10)));
            ps.setLong(3, 2);

            int rowCount = ps.executeUpdate();
            System.out.printf("%s (rows) updated.%n", rowCount);

            selectAlbum(conn, 2L);

            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * Executes a SQL query to select an album from the database based on the
     * provided ID.
     *
     * @param conn the Connection object representing the database connection
     * @param id   the ID of the album to be selected
     * @throws SQLException if a database access error occurs or the SQL query
     * is invalid
     */
    private static void selectAlbum(Connection conn, Long id) throws SQLException {
        String sql = "select * from album where id = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setLong(1, id);

        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            System.out.printf("id=%s, title=%s, released_date=%s%n",
                    rs.getLong("id"), rs.getString("title"),
                    rs.getDate("release_date"));
        }
    }
}

The following is an output produced by the code snippet above:

id=2, title=With the Beatles, released_date=1963-11-22
1 (rows) updated.
id=2, title=A Hard Day's Night, released_date=1964-07-10

Maven Dependencies

<dependency>
    <groupId>io.github.spannm</groupId>
    <artifactId>ucanaccess</artifactId>
    <version>5.1.1</version>
</dependency>

Maven Central