flex 学习项目中总结的时间处理工具类DateUtils

7 篇文章 0 订阅
本文介绍了一个基于Flex的应用程序中使用的日期处理工具类DateUtils。该工具类提供了丰富的日期操作功能,包括日期加减、比较、格式化以及获取日期部分等。通过这些实用的方法,可以有效地简化Flex应用中的日期处理逻辑。
摘要由CSDN通过智能技术生成

 

关键字: flex 学习项目中总结的时间处理工具类dateutils


package util{

 import mx.formatters.DateFormatter;
 import mx.utils.ObjectUtil;
 import mx.utils.StringUtil;

 public class DateUtils {
  
  // Days of week
  public static const MONDAY:String  = "monday";
  public static const TUESDAY:String  = "tuesday";
  public static const WEDNESDAY:String = "wednesday";
  public static const THURSDAY:String  = "thursday";
  public static const FRIDAY:String  = "friday";
  public static const SATURDAY:String  = "saturday";
  public static const SUNDAY:String  = "sunday";
  
  // Months of year
  public static const JANUARY:String  = "january";
  public static const FEBRUARY:String  = "february";
  public static const MARCH:String  = "march";
  public static const APRIL:String  = "april";
  public static const MAY:String   = "may";
  public static const JUNE:String   = "june";
  public static const JULY:String   = "july";
  public static const AUGUST:String  = "august";
  public static const SEPTEMBER:String = "september";
  public static const OCTOBER:String  = "october";
  public static const NOVEMBER:String  = "november";
  public static const DECEMBER:String  = "december";

  // Date parts
  public static const YEAR:String   = "fullYear";
  public static const MONTH:String  = "month";
  public static const WEEK:String   = "week";
  public static const DAY_OF_MONTH:String = "date";
  public static const HOURS:String  = "hours";
  public static const MINUTES:String  = "minutes";
  public static const SECONDS:String  = "seconds";
  public static const MILLISECONDS:String = "milliseconds";
  public static const DAY_OF_WEEK:String = "day";
  
  // Numeric value of "last", to get last item for a specific time
  public static const LAST:Number   = -1;
  
  // Date masks
  public static const SHORT_DATE_MASK:String = "MM/DD/YY";
  public static const MEDIUM_DATE_MASK:String = "MMM D, YYYY";
  public static const LONG_DATE_MASK:String = "MMMM D, YYYY";
  public static const FULL_DATE_MASK:String = "EEEE, MMMM D, YYYY";
  
  // Time masks
  public static const SHORT_TIME_MASK:String = "L:NN A";
  public static const MEDIUM_TIME_MASK:String = "L:NN:SS A";
  // TZD = TimeZoneDesignation = GMT + or - X hours, non-standard, requires a slight hack
  public static const LONG_TIME_MASK:String = MEDIUM_TIME_MASK + " TZD";
  
  // Internal values for using in date/time calculations
  private static const SECOND_VALUE:uint = 1000;
  private static const MINUTE_VALUE:uint = DateUtils.SECOND_VALUE * 60;
  private static const HOUR_VALUE:uint = DateUtils.MINUTE_VALUE * 60;
  private static const DAY_VALUE:uint  = DateUtils.HOUR_VALUE * 24;
  private static const WEEK_VALUE:uint = DateUtils.DAY_VALUE * 7;
  
  // Internal variable used in date/time formatting
  private static var _dateFormatter:DateFormatter;
  private static function get dateFormatter():DateFormatter {
   if ( !_dateFormatter ) {
    _dateFormatter = new DateFormatter;
   }
   return _dateFormatter;
  }
  
  // a generic object for holding day of the week values
  private static var _objDaysOfWeek:Object = null;
  public static function get objDaysOfWeek():Object {
   if ( !_objDaysOfWeek ) {
    _objDaysOfWeek = {};
    _objDaysOfWeek[ DateUtils.SUNDAY ]  = 0;
    _objDaysOfWeek[ DateUtils.MONDAY ]  = 1;
    _objDaysOfWeek[ DateUtils.TUESDAY ]  = 2;
    _objDaysOfWeek[ DateUtils.WEDNESDAY ] = 3;
    _objDaysOfWeek[ DateUtils.THURSDAY ] = 4;
    _objDaysOfWeek[ DateUtils.FRIDAY ]  = 5;
    _objDaysOfWeek[ DateUtils.SATURDAY ] = 6;
   }
   return _objDaysOfWeek;
  }
  
  // a generic object for holding month values
  private static var _objMonth:Object = null;
  public static function get objMonth():Object {
   if ( !_objMonth ) {
    _objMonth = {};
    _objMonth[ DateUtils.JANUARY ]  = 0;
    _objMonth[ DateUtils.FEBRUARY ]  = 1;
    _objMonth[ DateUtils.MARCH ]  = 2;
    _objMonth[ DateUtils.APRIL ]  = 3;
    _objMonth[ DateUtils.MAY ]   = 4;
    _objMonth[ DateUtils.JUNE ]   = 5;
    _objMonth[ DateUtils.JULY ]   = 6;
    _objMonth[ DateUtils.AUGUST ]  = 7;
    _objMonth[ DateUtils.SEPTEMBER ] = 8;
    _objMonth[ DateUtils.OCTOBER ]  = 9;
    _objMonth[ DateUtils.NOVEMBER ]  = 10;
    _objMonth[ DateUtils.DECEMBER ]  = 11;
   }
   return _objMonth;
  }
  
  public function DateUtils() {
  }
    /**
   *
   * 添加或减少天数
   */
  public static function  addDay(date:Date,days:int):Date
  {
   if(date!=null)
   {
    date.setDate(days);
   }
   return date;
  }
  /**
   * 两个日期相差的天数
   *
   */
  public static function  daysOfDates(date0:Date,date1:Date):int
  { 
   var days0:Number=date0.time;
   var days1:Number=date1.time;
   var days:Number=(days0-days1)/DAY_VALUE;
   return days;
  }
  
 
  /**
   * 判断时间是否在开始和结束时间之间
   *
   */
  public static function  isBetween(fromdate:Date,todate:Date,current:Date):Boolean
  {
    if(ObjectUtil.dateCompare(fromdate,current)!==1&&ObjectUtil.dateCompare(todate,current)!=-1)
    {
       return true;
    }
    return false;
  }
  /**
   *位于某个时间之后
   */
  public static function  after(date0:Date,date1:Date):Boolean
  {
          if(ObjectUtil.dateCompare(date0,date1)==1)
    {
      return true;
    }
    return false;
  }
  /**
   *位于某个时间之前
   */
  public  static function  before(date0:Date,date1:Date):Boolean
  {
    if(ObjectUtil.dateCompare(date0,date1)==-1)
    {
      return true;
    }
    return false;
  }
  
         /**
   *两个时间相等
   */
  public static function  equals(date0:Date,date1:Date):Boolean
  {
    if(ObjectUtil.dateCompare(date0,date1)==0)
    {
      return true;
    }
    return false;
  }
  /**
   * @private
   *
   * This function will remove any invalid characters from the date/time mask based upon a pattern
   *
   * @param mask   The string for matching
   * @param pattern  The valid characters for this mask
   * @param defaultValue The default value to return to the calling page should the mask not match the pattern
   *
   * @return    Returns a validated <code>mask</code> based upon the original pattern
   */
  private static function removeInvalidDateTimeCharacters( mask:String, pattern:String, defaultValue:String ):String {
   // test for invalid date and time characters
   if ( mask.replace( new RegExp( pattern, "ig" ), "" ).length > 0 ) {
    // if user is passing an invalid mask, default to defaultValue
    mask = defaultValue;
   }
   // temporarily replace TZD with lowercase tzd for replacing later
   return mask.replace( new RegExp( "TZD", "i" ), "tzd" );
  }
  
  /**
   * Formats a date into a certain date/time format
   *
   * @param date The date to format
   * @param mask How the date should be formatted
   *
   * @return  A formatted date
   */
  public static function dateTimeFormat( date:Date, mask:String="MM/DD/YYYY L:NN:SS A" ):String {
   return buildDateTime( date, mask, "(Y|M|D|E|A|J|H|K|L|N|S|TZD|//W)+", DateUtils.SHORT_DATE_MASK + ' ' + DateUtils.SHORT_TIME_MASK );
  }
  
  /**
   * Formats a time into a certain time format
   *
   * @param date The date to format
   * @param mask How the date should be formatted
   *
   * @return  A formatted time
   */
  public static function timeFormat( date:Date, mask:String=DateUtils.SHORT_TIME_MASK ):String {
   return buildDateTime( date, mask, "(A|:|J|H|K|L|N|S|TZD|//s)+", DateUtils.SHORT_TIME_MASK );
  }
  
  /**
   * Formats a date into a certain date format
   *
   * @param date The date to format
   * @param mask How the date should be formatted
   *
   * @return  A formatted date
   */
  public static function dateFormat( date:Date, mask:String=DateUtils.SHORT_DATE_MASK ):String {
   return buildDateTime( date, mask, "(Y|M|D|E|//W)+", DateUtils.SHORT_DATE_MASK );
  }
  
  /**
   * @private
   *
   * Formats a date into a certain date/time format
   *
   * @param date   The date to format
   * @param mask   The string for matching
   * @param pattern  The valid characters for this mask
   * @param defaultValue The default value to return to the calling page should the mask not match the pattern
   *
   * @return  A formatted date
   */
  private static function buildDateTime( date:Date, mask:String, pattern:String, defaultValue:String ):String {
   dateFormatter.formatString = removeInvalidDateTimeCharacters( mask, pattern, defaultValue );
   
   return dateFormatter.format( date ).replace( new RegExp( "TZD", "i" ), buildTimeZoneDesignation( date ) );
  }
  
  /**
   * @private
   *
   * Calculates a timeZoneOffset, and converts it to a string, in standard GMT XX:XX format
   *
   * @param date The date on which to calculate the offset
   *
   * @return  The formatted time zone designation
   */
  private static function buildTimeZoneDesignation( date:Date ):String {
   if ( !date ) {
    return "";
   }
   var timeZoneAsString:String = "GMT ";
   // timezoneoffset is the number that needs to be added to the local time to get to GMT, so
   // a positive number would actually be GMT -X hours
   if ( date.getTimezoneOffset() / 60 > 0 && date.getTimezoneOffset() / 60 < 10 ) {
    timeZoneAsString += "-0" + ( date.getTimezoneOffset() / 60 ).toString();
   } else if ( date.getTimezoneOffset() < 0 && date.timezoneOffset / 60 > -10 ) {
    timeZoneAsString += "0" + ( -1 * date.getTimezoneOffset() / 60 ).toString();
   }
   // add zeros to match standard format
   timeZoneAsString += "00";

   return timeZoneAsString;
  }
  
  /**
   * Adds the specified number of "date parts" to a date, e.g. 6 days
   *
   * @param datePart The part of the date that will be added
   * @param number The total number of "dateParts" to add to the date
   * @param date  The date on which to add
   *
   * @return   The new date
   */
  public static function dateAdd( datePart:String, number:Number, date:Date ):Date {
   var _returnDate:Date = new Date( date );
  
   switch ( datePart ) {
    case DateUtils.YEAR:
    case DateUtils.MONTH:
    case DateUtils.DAY_OF_MONTH:
    case DateUtils.HOURS:
    case DateUtils.MINUTES:
    case DateUtils.SECONDS:
    case DateUtils.MILLISECONDS:
     _returnDate[ datePart ] += number;
     break;
    case DateUtils.WEEK:
     _returnDate[ DateUtils.DAY_OF_MONTH ] += number * 7;
     break;
    default:
     /* Unknown date part, do nothing. */
     break;
   }
   return _returnDate;
  }
  
  /**
   * Gets the day of the week
   *
   * @param date The date for which to get the day of the week
   *
   * @return  A number representing the day of the week, 0 to 6
   */
  public static function dayOfWeek( date:Date ):Number {
   return date.getDay();
  }
  
  /**
   * Gets the ordinal value or day of the year
   *
   * @param date The date for which to get the day of the year
   *
   * @return  A number representing the day of the year, 1 to 365 or 366 for a leap year
   */
  public static function dayOfYear( date:Date ):Number {
   // add one as it has to include first of year
   return DateUtils.dateDiff( DateUtils.DAY_OF_MONTH, new Date( date.fullYear, DateUtils.monthAsNumber( DateUtils.JANUARY ), 1 ), date ) + 1;
  }
  
  /**
   * Gets the week of the year
   *
   * @param date The date for which to get the week of the year
   *
   * @return  A number representing the week of the year, 1 to 53 ( as there are slightly more than 52 weeks of days in a year)
   */
  public static function weekOfYear( date:Date ):Number {
   return Math.ceil( DateUtils.dayOfYear( date ) / 7 );
  }
  
  /**
   * Converts the day of the week to a Flex day of the week
   *
   * @param date The human readable day of week
   *
   * @return  The Flex converted day of week or 0 aka Sunday
   */
  public static function toFlexDayOfWeek( localDayOfWeek:Number ):Number {
   return ( localDayOfWeek > 0 && localDayOfWeek < 8 ) ? localDayOfWeek - 1 : 0;
  }
  
  /**
   * Gets the Xth day of the month.
   * e.g. get the 3rd Wednesday of the month
   *
   * @param iteration  The iteration of the month to get e.g. 4th or Last
   * @param strDayOfWeek The day of the week as a string
   * @param date   The date containing the month and year
   *
   * @return    The date of the xth dayOfWeek of the month
   */
  public static function dayOfWeekIterationOfMonth( iteration:Number, strDayOfWeek:String, date:Date ):Date {
   // get the numeric day of the week for the requested day
   var _dayOfWeek:Number = dayOfWeekAsNumber( strDayOfWeek );
   // get the date for the first of the month
   var _firstOfMonth:Date = new Date( date.fullYear, date.month, 1 );
   // calculate how many days to add to get to the requested day from the first of the month
   var _daysToAdd:Number = _dayOfWeek - DateUtils.dayOfWeek( _firstOfMonth );
   // if dayOfWeek is before the first of the month, get the dayOfWeek for the following week
   if ( _daysToAdd < 0 ) {
    _daysToAdd += 7;
   }
   // set the date to the first day of the week for the requested date
   var _firstDayOfWeekOfMonth:Date = DateUtils.dateAdd( DateUtils.DAY_OF_MONTH, _daysToAdd, _firstOfMonth );
   // return the date if iteration is 1
   if ( iteration == 1 ) {
    return _firstDayOfWeekOfMonth;
   } else {
    // if requesting an iteration that is more than is in that month or requesting the last day of week of month
    // return last date for that day of week of month
    if ( ( DateUtils.totalDayOfWeekInMonth( strDayOfWeek, date ) < iteration ) || ( iteration == DateUtils.LAST ) ) {
     iteration = DateUtils.totalDayOfWeekInMonth( strDayOfWeek, date );
    }
    // subtract 1 as it starts from the first dayOfWeek of month
    return DateUtils.dateAdd( DateUtils.WEEK, iteration - 1, _firstDayOfWeekOfMonth );
   }
  }
  
  /**
   * Gets the days in the month
   *
   * @param date The date to check
   *
   * @return  The number of days in the month
   */
  public static function daysInMonth( date:Date ):Number {
   // get the first day of the next month
   var _localDate:Date = new Date( date.fullYear, DateUtils.dateAdd( DateUtils.MONTH, 1, date ).month, 1 );
   // subtract 1 day to get the last day of the requested month
   return DateUtils.dateAdd( DateUtils.DAY_OF_MONTH, -1, _localDate ).date;
  }
  
  /**
   * Gets the total number of dayOfWeek in the month
   *
   * @param strDayOfWeek The day of week to check
   * @param date   The date containing the month and year
   *
   * @return    The number of <code>strDayOfWeek</code> in that month and year
   */
  public static function totalDayOfWeekInMonth( strDayOfWeek:String, date:Date ):Number {
   var _startDate:Date = DateUtils.dayOfWeekIterationOfMonth( 1, strDayOfWeek, date );
   var _totalDays:Number = DateUtils.dateDiff( DateUtils.DAY_OF_MONTH, _startDate, new Date( date.fullYear, date.month, DateUtils.daysInMonth( date ) ) );
   // have to add 1 because have to include first day that is found i.e. if wed is on 2nd of 31 day month, would total 5, of if wed on 6th, would total 4
   return Math.floor( _totalDays / 7 ) + 1;
  }
  
  /**
   * Converts the month to a Flex month
   *
   * @param date The human readable month
   *
   * @return  The Flex converted month or 0 aka January
   */
  public static function toFlexMonth( localMonth:Number ):Number {
   return ( localMonth > 0 && localMonth < 13 ) ? localMonth - 1 : 0;
  }
  
  /**
   * Determines whether a value is actually a valid date
   *
   * @param value The date value
   *
   * @return  <code>true</code> means this is a valid date, <code>false</code> means it is not a valid date
   */
  public static function isDate( value:String ):Boolean {
   return Date.parse( value ) > 0;
  }
  
  /**
   * Formats a date to the string version of the day of the week
   *
   * @param date The date to format
   *
   * @return  A formatted day of week
   */
  public static function dayOfWeekAsString( date:Date ):String {
   return DateUtils.dateFormat( date, "EEEE" );
  }
  
  /**
   * Formats a date to the numeric version of the day of the week
   *
   * @param strDayOfWeek The day of week to convert
   *
   * @return    A formatted day of week or -1 if day not found
   */
  public static function dayOfWeekAsNumber( strDayOfWeek:String ):Number {
   return ( objDaysOfWeek[ strDayOfWeek ] >= 0 ) ? objDaysOfWeek[ strDayOfWeek ] : -1;
  }
  
  /**
   * Formats a date to the string version of the month
   *
   * @param date The date to format
   *
   * @return  A formatted month
   */
  public static function monthAsString( date:Date ):String {
   return DateUtils.dateFormat( date, "MMMM" );
  }
  
  /**
   * Formats a month to the numeric version of the month
   *
   * @param strMonth The month to convert
   *
   * @return   A formatted month or -1 if month not found
   */
  public static function monthAsNumber( strMonth:String ):Number {
   return ( objMonth[ strMonth ] >= 0 ) ? objMonth[ strMonth ] : -1;
  }
  
  /**
   * Gets the number of days in the year
   *
   * @param date The date to check
   *
   * @return  The total number of days in the year
   */
  public static function daysInYear( date:Date ):Number {
   return DateUtils.dateDiff(
      DateUtils.DAY_OF_MONTH,
      new Date( date.fullYear, DateUtils.monthAsNumber( DateUtils.JANUARY ), 1 ),
      DateUtils.dateAdd( DateUtils.YEAR, 1, new Date( date.fullYear, DateUtils.monthAsNumber( DateUtils.JANUARY ), 1 ) ) );
  }
  
  /**
   * Determines whether the year is a leap year or not
   *
   * @param date The date to check
   *
   * @return  <code>true</code> means it is a leap year, <code>false</code> means it is not a leap year.
   */
  public static function isLeapYear( date:Date ):Boolean {
   return daysInYear( date ) > 365;
  }
  
  /**
   * Determines the number of "dateParts" difference between 2 dates
   *
   * @param datePart The part of the date that will be checked
   * @param startDate The starting date
   * @param endDate The ending date
   *
   * @return   The number of "dateParts" difference
   */
  public static function dateDiff( datePart:String, startDate:Date, endDate:Date ):Number {
   var _returnValue:Number = 0;

   switch ( datePart ) {
    case DateUtils.MILLISECONDS:
     _returnValue = endDate.time - startDate.time;
     break;
    case DateUtils.SECONDS:
     _returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.SECOND_VALUE );
     break;
    case DateUtils.MINUTES:
     _returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.MINUTE_VALUE );
     break;
    case DateUtils.HOURS:
     _returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.HOUR_VALUE );
     break;
    case DateUtils.DAY_OF_MONTH:
     // TODO: Need to figure out DST problem i.e. 23 hours at DST start, 25 at end.
     // Math.floor causes rounding down error with DST start at dayOfYear
     _returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.DAY_VALUE );
     break;
    case DateUtils.WEEK:
     _returnValue = Math.floor( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) / DateUtils.WEEK_VALUE );
     break;
    case DateUtils.MONTH:
     // if start date is after end date, switch values and take inverse of return value
     if ( DateUtils.dateDiff( DateUtils.MILLISECONDS, startDate, endDate ) < 0 ) {
      _returnValue -= DateUtils.dateDiff( DateUtils.MONTH, endDate, startDate );
     } else {
       // get number of months based upon years
      _returnValue = DateUtils.dateDiff( DateUtils.YEAR, startDate, endDate ) * 12;
      // subtract months then perform test to verify whether to subtract one month or not
      // the check below gets the correct starting number of months (but may need to have one month removed after check)
      if ( endDate.month != startDate.month ) {
       _returnValue += ( endDate.month <= startDate.month ) ? 12 - startDate.month + endDate.month : endDate.month - startDate.month;
      }
      // have to perform same checks as YEAR
      // i.e. if end date day is <= start date day, and end date milliseconds < start date milliseconds
      if ( ( endDate[ DateUtils.DAY_OF_MONTH ] < startDate[ DateUtils.DAY_OF_MONTH ] ) ||
        ( endDate[ DateUtils.DAY_OF_MONTH ] == startDate[ DateUtils.DAY_OF_MONTH ] &&
         endDate[ DateUtils.MILLISECONDS ] < startDate[ DateUtils.MILLISECONDS ] ) ) {
       _returnValue -= 1;
      }
     }
     break;
    case DateUtils.YEAR:
     _returnValue = endDate.fullYear - startDate.fullYear;
     // this fixes the previous problem with dates that ran into 2 calendar years
     // previously, if 2 dates were in separate calendar years, but the months were not > 1 year apart, then it was returning too many years
     // e.g. 11/2008 to 2/2009 was returning 1, but should have been returning 0 (zero)
     // if start date before end date and months are less than 1 year apart, add 1 to year to fix offset issue
     // if end date before start date and months are less than 1 year apart, subtract 1 year to fix offset issue
     // added month and milliseconds check to make sure that a date that was e.g. 9/11/07 9:15AM would not return 1 year if the end date was 9/11/08 9:14AM
     if ( _returnValue != 0 ) {
      // if start date is after end date
      if ( _returnValue < 0 ) {
       // if end date month is >= start date month, and end date day is >= start date day, and end date milliseconds > start date milliseconds
       if ( ( endDate[ DateUtils.MONTH ] > startDate[ DateUtils.MONTH ] ) ||
         ( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] > startDate[ DateUtils.DAY_OF_MONTH ] ) ||
         ( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] == startDate[ DateUtils.DAY_OF_MONTH ] &&
          endDate[ DateUtils.MILLISECONDS ] > startDate[ DateUtils.MILLISECONDS ] ) ) {
        _returnValue += 1;
       }
      } else {
       // if end date month is <= start date month, and end date day is <= start date day, and end date milliseconds < start date milliseconds
       if ( ( endDate[ DateUtils.MONTH ] < startDate[ DateUtils.MONTH ] ) ||
         ( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] < startDate[ DateUtils.DAY_OF_MONTH ] ) ||
         ( endDate[ DateUtils.MONTH ] == startDate[ DateUtils.MONTH ] && endDate[ DateUtils.DAY_OF_MONTH ] == startDate[ DateUtils.DAY_OF_MONTH ] &&
          endDate[ DateUtils.MILLISECONDS ] < startDate[ DateUtils.MILLISECONDS ] ) ) {
        _returnValue -= 1;
       }
      }
     }
     break;
   
   }

   return _returnValue;
   
  }
  
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值