Tous les produits
Search
Centre de documentation

Object Storage Service:Comment éviter les frais de stockage pour une durée inférieure à la durée minimale

Dernière mise à jour :Aug 18, 2026

Les objets stockés dans les classes de stockage Infrequent Access (IA), Archive, Cold Archive et Deep Cold Archive sont soumis à une durée minimale de conservation. Si vous modifiez la classe de stockage d'un objet ou si vous le supprimez avant l'expiration de cette durée minimale, des frais vous seront facturés pour la période non écoulée. Pour éviter ces coûts inutiles, il est essentiel de savoir déterminer si les objets de différentes classes de stockage respectent la durée minimale requise. Assurez-vous que cette condition est remplie avant de convertir la classe de stockage d'un objet ou de le supprimer.

Classe de stockage et durée minimale de conservation

Classe de stockage

Durée minimale de conservation

Méthode de calcul

Standard

S/O

S/O

Infrequent Access

30

Basée sur la date de dernière modification des objets.

Archive

60

Basée sur la date de dernière modification des objets.

Cold Archive

180

Basée sur la date de conversion de la classe de stockage des objets en Cold Archive.

Deep Cold Archive

180

Basée sur la date de conversion de la classe de stockage des objets en Deep Cold Archive.

Exemples

L'exemple de code suivant illustre comment interroger les métadonnées d'un objet et comparer les valeurs des paramètres LastModified et TransitionTime avec l'heure actuelle afin de déterminer si l'objet respecte la durée minimale de conservation :

Java

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.common.utils.DateUtil;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.HeadObjectRequest;
import com.aliyuncs.exceptions.ClientException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Demo {

    public static void main(String[] args) throws ClientException {
        // Set yourEndpoint to the endpoint of the region where the bucket is located.
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Specify the region that corresponds to the endpoint, such as cn-hangzhou.
        String region = "cn-hangzhou";
        // Obtain access credentials from environment variables. Before you run this code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the bucket name.
        String bucketName = "examplebucket";

        // Create an OSSClient instance.
        // When the OSSClient instance is no longer in use, call the shutdown method to release its resources.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // Explicitly specify Signature Version 4.
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        // Specify the full paths of the objects that you want to check.
        String[] objectNames = {"example.txt"};

        // A map of storage classes to minimum storage durations in days.
        Map<String, Integer> minimumRetentionPeriod = new HashMap<>();
        minimumRetentionPeriod.put("Standard", 0);
        minimumRetentionPeriod.put("IA", 30);
        minimumRetentionPeriod.put("Archive", 60);
        minimumRetentionPeriod.put("ColdArchive", 180);
        minimumRetentionPeriod.put("DeepColdArchive", 180);

        for (String objectName : objectNames) {
            objectName = objectName.trim();
            try {
                // Obtain the object metadata.
                HeadObjectRequest headObjectRequest = new HeadObjectRequest(bucketName, objectName);
                ObjectMetadata objectMetadata = ossClient.headObject(headObjectRequest);

                // Obtain the storage class and the last modified time.
                String storageClass = String.valueOf(objectMetadata.getObjectStorageClass());
                String lastModifiedStr = objectMetadata.getLastModified().toString();
                Date lastModified = objectMetadata.getLastModified();

                if ("ColdArchive".equals(storageClass) || "DeepColdArchive".equals(storageClass)) {
                    Object transitionTimeObj = objectMetadata.getRawMetadata().get("x-oss-transition-time");
                    String transitionTimeStr = String.valueOf(transitionTimeObj);
                    Date transitionTime = DateUtil.parseRfc822Date(transitionTimeStr);

                    if (transitionTime != null) {
                        lastModified = transitionTime;
                    } else {
                        throw new Exception("The storage class of object '" + objectName + "' is " + storageClass
                                + ", and the x-oss-transition-time is " + transitionTimeStr + ".");
                    }
                }

                // Obtain the current time.
                Date currentTime = new Date();

                // Calculate the storage duration in days.
                long storageDuration = (currentTime.getTime() - lastModified.getTime()) / (1000 * 60 * 60 * 24);

                // Print the information.
                System.out.println("Object Name: " + objectName);
                System.out.println("Storage Class: " + storageClass);
                System.out.println("Last Modified Time: " + lastModifiedStr);
                System.out.println("Storage Duration: " + storageDuration + " days");

                // Check whether the minimum storage duration is met.
                if (minimumRetentionPeriod.containsKey(storageClass)) {
                    int minRetention = minimumRetentionPeriod.get(storageClass);
                    if (storageDuration < minRetention) {
                        int daysRemaining = minRetention - (int) storageDuration;
                        System.out.println(objectName + " has not met the minimum storage duration. It must be stored for another " + daysRemaining + " days. If you delete the object earlier, you are charged for storage fees for the remaining "
                                + daysRemaining + " days of the minimum retention period.");
                    } else {
                        int daysExceeded = (int) storageDuration - minRetention;
                        System.out.println(objectName + " has met the minimum storage duration. The exceeded duration is " + daysExceeded + " days. No fees are charged for early deletion.");
                    }
                } else {
                    System.out.println("The storage class of " + objectName + " is not recognized.");
                }
                System.out.println("----------------------------------------");  // Separator
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("An error occurred while obtaining the metadata of " + objectName + ": " + e.getMessage());
                System.out.println("----------------------------------------");  // Separator
            }
        }

        // Shut down the OSSClient.
        ossClient.shutdown();
    }
}

Python

import datetime
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
# Specify the name of the bucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# Specify the full path of the single object. 
object_names = ['example.txt']

# The mapping between the storage class and the minimum storage duration. Unit: days. 
minimum_retention_period = {
    'Standard': 0,
    'IA': 30,
    'Archive': 60,
    'ColdArchive': 180,
    'DeepColdArchive': 180
}

for object_name in object_names:
    object_name = object_name.strip()

    try:
        # Query all object metadata using the head_object method. 
        object_info = bucket.head_object(object_name)

        # Query the storage class and last modified time of the object. 
        storage_class = object_info.headers['x-oss-storage-class']
        last_modified = object_info.headers['Last-Modified']

        # Change the last modified time to the datetime object. 
        last_modified_time = datetime.datetime.strptime(last_modified, '%a, %d %b %Y %H:%M:%S GMT')

        transition_time_str = object_info.headers.get('x-oss-transition-time')
        transition_time = None
        if storage_class == 'ColdArchive' or storage_class == 'DeepColdArchive':
            if transition_time_str:
                last_modified_time = datetime.datetime.strptime(transition_time_str, "%a, %d %b %Y %H:%M:%S %Z")
            else:
                raise Exception(f"Storage class of '{object_name}': {storage_class}. x-oss-transition-time: {transition_time_str}.")

        # Query the current time. 
        current_time = datetime.datetime.now()

        # Calculate the storage duration of the object. Unit: days. 
        storage_duration = (current_time - last_modified_time).days

        # Display the object information. 
        print(f "Object name: {object_name}")
        print(f "Storage class: {storage_class}")
        print(f "Created at: {last_modified}")
        print(f "Storage duration: {storage_duration} days")

        # Determine whether the object meets the minimum storage duration requirements. 
        if storage_class in minimum_retention_period:
            min_retention = minimum_retention_period[storage_class]
            if storage_duration < min_retention:
                days_remaining = min_retention - storage_duration
                print(f"{object_name} does not meet the minimum storage duration requirements. The object needs to be stored for another {days_remaining} days. If you delete the object, you are charged {days_remaining} days of the storage usage for the object that is stored for less than the minimum storage duration.")
            else:
                days_exceeded = storage_duration - min_retention
                print(f"{object_name} meets the minimum storage duration requirements. The object is stored {days_exceeded} days more than the minimum storage duration. You are not charged for the storage usage for the object that is stored for less than the minimum storage duration.")
        else:
            print(f"The storage class of {object_name} is not recognized.")

        print("-" * 40) # The delimiter.

    except Exception as e:
        print(f "An error occurred when I query the metadata of {object_name}: {str(e)}")
        print("-" * 40) # The delimiter 

Node.js

const OSS = require("ali-oss");

// Obtain access credentials from environment variables. Before running this code sample, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
const config = {
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  // Set region to the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set region to oss-cn-hangzhou.
  region: "oss-cn-hangzhou",
  // Specify the bucket name.
  bucket: "examplebucket",
};
const client = new OSS(config);

// Mapping between storage classes and minimum storage durations in days.
const minimum_retention_period = {
  Standard: 0,
  IA: 30,
  Archive: 60,
  ColdArchive: 180,
  DeepColdArchive: 180,
};

// Calculate the difference between two dates in days.
function getDays(date1, date2) {
  if (!(date1 instanceof Date) || !(date2 instanceof Date)) {
    throw new Error("Valid Date objects must be passed.");
  }
  const timestamp1 = date1.getTime();
  const timestamp2 = date2.getTime();
  const diffInMilliseconds = Math.abs(timestamp2 - timestamp1);
  const diffInDays = diffInMilliseconds / (1000 * 60 * 60 * 24);

  return Math.round(diffInDays);
}

// Specify the full path of the object to check.
const object_names = ["example.jpg"];

(async () => {
  for (const object_name of object_names) {
    try {
      // Obtain all metadata of the object using the head method.
      const object_info = await client.head(object_name);
      const { headers } = object_info.res;

      // Obtain the storage class and the last modified time.
      const storage_class = headers["x-oss-storage-class"];
      const last_modified = headers["last-modified"];

      let last_modified_time = new Date(last_modified);
      const transition_time_str = headers["x-oss-transition-time"];
      if (["ColdArchive", "DeepColdArchive"].includes(storage_class)) {
        if (transition_time_str)
          last_modified_time = new Date(transition_time_str);
        else {
          const errorStr = `The storage class of object '${object_name}' is ${storage_class}, but the x-oss-transition-time is ${transition_time_str}. The x-oss-transition-time header is available only for objects transitioned to Cold Archive or Deep Cold Archive using lifecycle rules.`;
          throw new Error(errorStr);
        }
      }

      const current_time = new Date(); // Obtain the current time.
      const storage_duration = getDays(current_time, last_modified_time); // Calculate the storage duration in days.
      // Print the information.
      console.log(`Object name: ${object_name}`);
      console.log(`Storage class: ${storage_class}`);
      console.log(`Last modified time: ${last_modified}`);
      console.log(`Storage duration: ${storage_duration} days`);

      // Check whether the minimum storage duration is met.
      if (Object.keys(minimum_retention_period).includes(storage_class)) {
        min_retention = minimum_retention_period[storage_class];
        if (storage_duration < min_retention) {
          const days_remaining = min_retention - storage_duration;
          console.log(
            `${object_name} has not met the minimum storage duration. Deleting the object now will incur fees for the remaining ${days_remaining} days of the minimum storage period.`
          );
        } else {
          const days_exceeded = storage_duration - min_retention;
          console.log(
            `${object_name} has met the minimum storage duration. The storage duration has exceeded the minimum by ${days_exceeded} days. No early deletion fees will be incurred if you delete the object.`
          );
        }
      } else console.log(`The storage class of ${object_name} is not recognized.`);
    } catch (e) {
      console.log(`An error occurred while obtaining the metadata of ${object_name}:`, e);
    }
  }
})();

PHP

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;

// Specify the endpoint of the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
$endpoint = 'http://oss-cn-hangzhou.aliyuncs.com';
// Specify the bucket name.
$bucketName = 'examplebucket';

// Create an OssClient instance.
try {
    // Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
    $provider = new EnvironmentVariableCredentialsProvider();
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
	// Specify the full path of the object that you want to check.
    $objectNames = ['example.txt'];
    $minimumRetentionPeriod = [
        'Standard' => 0,
        'IA' => 30,
        'Archive' => 60,
        'ColdArchive' => 180,
        'DeepColdArchive' => 180,
    ];

    foreach ($objectNames as $objectName) {
        $objectName = trim($objectName);
        try {
            // Obtain all the metadata of the object using the getObjectMeta method.
            $objectInfo = $ossClient->getObjectMeta($bucketName, $objectName);

            // Obtain the storage class and the last modified time.
            $storageClass = $objectInfo['x-oss-storage-class'];
            $lastModified = $objectInfo['last-modified'];

            // Convert the last modified time to a UNIX timestamp.
            $lastModifiedTime = strtotime($lastModified);

            if (in_array($storageClass, array("ColdArchive", "DeepColdArchive")) && isset($objectInfo["x-oss-transition-time"])) {
                $lastModifiedTime = strtotime($objectInfo["x-oss-transition-time"]);
            }

            // Get the current time.
            $currentTime = time();

            // Calculate the storage duration in days.
            $storageDuration = floor(($currentTime - $lastModifiedTime) / (60 * 60 * 24));

            // Print the information.
            echo "Object name: $objectName\n";
            echo "Storage class: $storageClass\n";
            echo "Last modified: $lastModified\n";
            echo "Storage duration: $storageDuration days\n";

            // Check whether the minimum storage duration is met.
            if (isset($minimumRetentionPeriod[$storageClass])) {
                $minRetention = $minimumRetentionPeriod[$storageClass];
                if ($storageDuration < $minRetention) {
                    $daysRemaining = $minRetention - $storageDuration;
                    echo "$objectName has not met the minimum storage duration. It must be stored for another $daysRemaining days. Deleting it early will incur fees for the remaining $daysRemaining days of the minimum storage period.\n";
                } else {
                    $daysExceeded = $storageDuration - $minRetention;
                    echo "$objectName has met the minimum storage duration, exceeding the requirement by $daysExceeded days. Deleting the object will not incur early deletion fees.\n";
                }
            } else {
                echo "The storage class of $objectName was not recognized.\n";
            }
            echo str_repeat("-", 40) . "\n"; // Separator
        } catch (OssException $e) {
            echo "An error occurred while obtaining the metadata of $objectName: " . $e->getMessage() . "\n";
            echo str_repeat("-", 40) . "\n"; // Separator
        }
    }
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

Go

package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

func main() {
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion("cn-hangzhou").
		WithEndpoint("https://oss-cn-hangzhou.aliyuncs.com")
	
	client := oss.NewClient(cfg)
	
	// Specify the full path of the object to check.
	objectNames := []string{"example.txt"}
	
	// Define the minimum storage duration in days for each storage class.
	minimumRetentionPeriod := map[string]int{
		"Standard":        0,
		"IA":              30,
		"Archive":         60,
		"ColdArchive":     180,
		"DeepColdArchive": 180,
	}
	
	// Set bucketName to the name of the bucket.
	bucketName := "examplebucket"
	
	for _, objectName := range objectNames {
		objectName = strings.TrimSpace(objectName)
		if objectName == "" {
			continue
		}
		
		// Get object metadata.
		objectInfo, err := client.HeadObject(context.TODO(), &oss.HeadObjectRequest{
			Bucket: oss.Ptr(bucketName),
			Key:    oss.Ptr(objectName),
		})
		if err != nil {
			log.Printf("An error occurred while getting metadata for %s: %v\n", objectName, err)
			continue
		}
		
		// Check if storageClass is empty.
		if objectInfo.StorageClass == nil {
			log.Printf("Warning: The storage class of %s is empty. Skipping check.\n", objectName)
			continue
		}
		
		storageClass := *objectInfo.StorageClass
		currentTime := time.Now().Unix()
		
		// Calculate the storage duration in days.
		storageDuration := (currentTime - objectInfo.LastModified.Unix()) / (60 * 60 * 24)
		
		// For Cold Archive and Deep Cold Archive, calculate from the transition time if it exists.
		if storageClass == "ColdArchive" || storageClass == "DeepColdArchive" {
			transitionTimeStr := objectInfo.Headers.Get("x-oss-transition-time")
			if transitionTimeStr != "" {
				transitionTime, err := time.Parse(http.TimeFormat, transitionTimeStr)
				if err != nil {
					log.Printf("Warning: Failed to parse x-oss-transition-time for %s: %v. Calculating based on creation time.\n", objectName, err)
				} else {
					storageDuration = (currentTime - transitionTime.Unix()) / (60 * 60 * 24)
				}
			}
		}
		
		// Print basic object information.
		fmt.Printf("Object name: %s\n", objectName)
		fmt.Printf("Storage class: %s\n", storageClass)
		fmt.Printf("Creation time: %s\n", objectInfo.LastModified.Format("2006-01-02 15:04:05"))
		fmt.Printf("Storage duration: %d days\n", storageDuration)
		
		// Check if the minimum storage duration is met.
		minRetention, exists := minimumRetentionPeriod[storageClass]
		if !exists {
			fmt.Printf("The storage class of %s is not recognized.\n", objectName)
			fmt.Println("----------------------------------------")
			continue
		}
		
		if minRetention == 0 {
			// The Standard storage class has no minimum storage duration.
			fmt.Printf("The storage class of %s is Standard, which has no minimum storage duration. No fees for insufficient storage duration will be incurred upon deletion.\n", objectName)
		} else {
			daysRemaining := minRetention - int(storageDuration)
			if daysRemaining > 0 {
				// The minimum storage duration is not met.
				fmt.Printf("%s has not met the minimum storage duration. It must be stored for another %d days. Deleting it early will incur fees for %d days of insufficient storage duration.\n",
					objectName, daysRemaining, daysRemaining)
			} else {
				// The minimum storage duration is met.
				fmt.Printf("%s has met the minimum storage duration (stored for %d days, required %d days). No fees for insufficient storage duration will be incurred upon deletion.\n",
					objectName, int(storageDuration), minRetention)
			}
		}
		
		fmt.Println("----------------------------------------")
	}
}

Références

Le code précédent montre comment interroger les métadonnées d'un objet via la méthode head_object et comparer les valeurs des paramètres LastModified et TransitionTime avec l'heure actuelle pour vérifier le respect de la durée minimale de conservation. Si vous souhaitez évaluer plusieurs objets simultanément, utilisez les opérations GetBucket (ListObjects), ListObjectVersions(GetBucketVersions) et ListBucketInventory.